2015-01-22 41 views
-1

我正試圖在我的Java項目中加載一個DLL,以允許我使用C#中的一些代碼。我做了一個樣本,並試圖實現它在我的Java項目,但我堅持收到以下錯誤,當我嘗試運行我的Java項目(設計師):我是收到使用JNI將C#加載到Java項目中的未解析鏈接錯誤

D:\RPMOpen\svnCobra\conversion\Designer>designer 

D:\RPMOpen\svnCobra\conversion\Designer>java -jar Designer.jar "D:/RPMOpen/svnCobra" 
Exception in thread "main" java.lang.UnsatisfiedLinkError: main/Designer.displayHeyLand()V 
     at main.Designer.main(Designer.java:491) 

我感到好奇的是關於在我設法修復的Java項目中加載DLL的錯誤,以及在我的Java項目的以下代碼中,如果我註釋掉最後一行,我的Designer現在可以正常工作。這暗示我的.DLL實際上正在加載,但真正讓我感到困惑的是爲什麼我收到UnsatisfiedLinkError。

Java項目的示例代碼:

static { 
     System.load("D://RPMOpen/svnCobra/Java/Designer/HeyLand.dll"); 
     } 

    public native void displayHeyLand(); 

    public static void main(String[] args) 
    { 
     if (args.length == 0) 
     { 
      throw new IllegalArgumentException("Conversion location required"); 
     } 



    cobraLocation = args[0]; 
      INPUT = cobraLocation + "/conversion/src/vb/"; 
      OUTPUT = cobraLocation + "/conversion/aui/Designer/"; 
      //System.loadLibrary(cobraLocation + "/conversion/Designer/GetFRXWrapper.dll"); 
      //String s = getFromFRX(); 
      //System.out.println(s); 

      Designer t = new Designer(); 
      t.displayHeyLand(); 

原始C#代碼試圖實現:

using System; 
using System.Windows.Forms; 

public class CSharpHeyLand 
{ 
    public CSharpHeyLand() { } 

    public void displayHeyLand() 
    { 
     MessageBox.Show("Hey Java, this is C#!", "Sample"); 
    } 
} 

元素從我的包裝,包括一個C++源文件和兩個頭文件的:

//Cpp file HeyLand.cpp ******************************************* 

#include <jni.h> 
#include "Java\HeyWork.h" 



// managed c++ header containing call to c# 
#include "MCPP\HeyLand.h" 

// JNI call to managed C++ Class 

JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand (JNIEnv *jn, jobject jobj) { 

    // istantiate the MC++ class. 
    HeyLandC* t = new HeyLandC(); 

    // actual call is made. 
    t->callCSharpHeyLand(); 
} 

//Header file HeyWork.h ******************************************* 

#include <jni.h> 
/* Header for class Test1 */ 

#ifndef _Included_Designer 
#define _Included_Designer 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  Designer 
* Method: displayHeyLand 
* Signature: (Ljava/lang/String;)V 
*/ 
JNIEXPORT void JNICALL Java_Main_Designer_displayHeyLand 
    (JNIEnv *, jobject); 

#ifdef __cplusplus 
} 
#endif 
#endif 

//Header file HeyLand.h ******************************************* 

#using <mscorlib.dll> 
#using "/CSharpHeyLand.netmodule" 

using namespace System; 

public __gc class HeyLandC 
{ 
    public: 
     // provide .NET interop and garbage collecting to the pointer 
     CSharpHeyLand __gc *t; 
     HeyLandC() { 
      t = new CSharpHeyLand(); 
      // Assign the reference a new instance of the object 
     } 

    // This inline function is called from the C++ Code 
     void callCSharpHeyLand() { 
      t->displayHeyLand(); 
     } 
}; 

任何幫助,非常感謝!

+0

我想我昨天看到了同樣的問題,你是否嘗試刪除「MessageBox.Show」句子,看看它是否可以? – Matt

+0

它仍然不好,昨天在我的大型項目中沒有實施的樣本在消息框中運行。 – HavelTheGreat

+0

嘗試使用進程監視器來監視java.exe以查看它如何加載DLL:https://technet.microsoft.com/en-us/sysinternals/bb896645。 – Matt

回答

0

幾個月前我遇到了同樣的錯誤。我們嘗試使用Java中的C#DLL,下面是我們所做的:

  1. 編寫一個C#DLL。
  2. 開發一個C++/CLI DLL作爲C#DLL的包裝,導出所需的函數。
  3. 在Java中,加載C++/CLI DLL並通過JNI調用函數。

加載C++/CLI DLL已經確定,就像你的情況下,執行一些代碼時,我們遇到了UnsatisfiedLinkError錯誤造成的,我們用Process Monitor追查,這是因爲java的exe文件未找到引用C#程序集。

與原生C++ DLL不同,當exe啓動時,引用的託管程序集不會立即加載it is loaded as needed,這種情況發生在JIT compiler在應用程序運行時第一次到達代碼時將MSIL代碼轉換爲本機代碼。這解釋了何時發生錯誤,當它到達該行代碼。

所以要弄清楚這個問題,你可以使用進程監視器來監視java.exe,看看它是如何加載DLL的。正如我所觀察到的,java exe會嘗試找到C#中的DLL:

  1. 首先在global assembly cache。(GAC)。 GAC中只有強名稱程序集。
  2. java.exe的文件夾。

因此,如果引用程序集不在兩個地方,您將遇到該錯誤。

+0

那麼,這個問題,我將不得不將我的DLL添加到GAC以及java.exe文件夾? – HavelTheGreat

+0

另外,奇怪的是,我的測試獨立工作。它只會在我在Eclipse中的大量Designer.java項目中輸入時產生此錯誤,而我的獨立測試是使用Notepad ++編寫的並在命令行上編譯的。這可能與它有關嗎? – HavelTheGreat

+0

任何一個地方都不錯。對於第二個問題,這應該不重要。 – Matt

0

您還可以創建一個DEVPATH環境變量,該環境變量引用託管DLL的存儲位置。在這種情況下,您必須在machine.config文件上設置developmentMode

相關問題