2011-12-30 62 views
6

我想在java中寫入c#中的dll方法。從下面的代碼中,我試圖構建成功生成的dll。在java中訪問dll方法

using System; 
using Microsoft.Win32; 


namespace CyberoamWinHelper 
{ 
    public class RegistryAccess 
    {   
     public static String getValue(String key) 
     { 
      RegistryKey rk = Registry.CurrentUser; 
      RegistryKey rk1=rk.OpenSubKey("Software\\Test", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl); 
      rk1.SetValue(key, "val1"); 
      return rk1.GetValue(key).ToString(); 
     } 
     public static void createSubkey(String name) 
     { 
      RegistryKey rk = Registry.CurrentUser; 
      rk.CreateSubKey("Software\\Test"); 
     } 
    } 
} 

在這之後我加載產生的dll在我的Java程序代碼是如下

public class JNI { 

    /** 
    * @param args the command line arguments 
    */ 
    public native String getValue(String key);  

    public static void main(String[] args) { 
     // TODO code application logic here 

     try 
     { 
      System.loadLibrary("CyberoamWinHelper"); 
      JNI j=new JNI();  
      System.out.println(j.getValue("abc")); 
     } 
     catch(UnsatisfiedLinkError e) 
     { 
      System.out.println("Ex" + e.getMessage()); 
     } 
    } 
} 

運行此代碼它給我下面的錯誤後。

"Exjni.JNI.getValue(Ljava/lang/String;)Ljava/lang/String;" 

那麼我不明白這個錯誤是什麼意思,但我想解決它。 還有一個問題,因爲我調用的方法是一種靜態方法,它會以這種方式調用嗎?我的意思是調用靜態方法,我們需要

「classname.methodname」

所以在這裏就可以調用的方法?

+0

你需要加載與'的System.loadLibrary(本地庫)' - 最好是在靜態初始化 – fge 2011-12-30 01:08:06

+0

@fge:我做到了 。它沒有工作。 – ankurtr 2011-12-30 01:12:42

+0

你當然知道,.NET DLL不是標準的DLL,並且它們本身不能與JNI一起工作。 – 2011-12-30 01:13:31

回答

7

只能通過JNI調用方法,如果這些方法實際上被設計成這樣調用的話。你的方法絕對不是。你在這裏做的事情(抱歉,如此直截了當)絕對沒有成功的機會 - 它不會以這種方式工作。

有幾種方法可以繼續。一個是瞭解JNI以及如何編寫實際可用的庫。 Here是這方面的標準參考。然而,用C#做這件事還是增加了一層複雜性。

另一種方法是完全放棄JNI並使用更合適的機制來訪問這些方法。你可以在這裏瞭解到JNA;它將完全更適合你的目標。

+1

@ ankur-trapasiya - 歐內斯特弗裏德曼希爾的建議絕對完全正確!請聽他的! – paulsm4 2011-12-30 01:24:05

+0

@ paulsm4:我正在嘗試與JNA合作。 – ankurtr 2011-12-30 17:19:35

0

您使用JNI不正確。在C#庫中使用JNI很困難(雖然不是不可能)。有一個很好的教程,如何去關於它here。在Google上進行C#JNI搜索應該會揭示更多。

你也應該調查類似Grasshopper ..

編輯

http://caffeine.berlios.de/site/documentation/quickstart.html

是一個很酷的解決方案。

+0

那麼第一個鏈接不是我想要做的。它關於visual C++和java。這是通過JNI完成的,但是我想在c#和java之間使用或不使用JNI。而在第二個環節也沒有回答我的問題。 – ankurtr 2011-12-30 01:22:27

+1

JNI與C#沒有直接接口..您必須在C#和Java之間創建一個C++存根。 – 2011-12-30 01:25:19

+0

哦,我爲你找到了一個很酷的解決方案。 jni4net是不錯的,由Jayan指定,但... – 2011-12-30 01:27:29

0

有用的網站:http://www.sahirshah.com/java/jni.html

嘗試:

public class myJNI { 

/** 
* @param args the command line arguments 
*/ 
public static native String getValue(String key);  
static 
{ 
    System.loadLibrary("CyberoamWinHelper"); 
} 
public static void main(String[] args) { 
    // TODO code application logic here 

    try 
    {  
     String myKey = "abc"; 
     System.out.println(getValue(myKey)); 
    } 
    catch(UnsatisfiedLinkError e) 
    { 
     System.out.println("Ex" + e.getMessage()); 
    } 
    } 
} 

您需要按照上面的鏈接描述來包裝DLL在C++ DLL。只需使用「javah -jni myJNI」命令生成一個頭文件並使用該頭文件中的函數簽名構建一個C++ dll。

看一看:http://www.codeproject.com/KB/cross-platform/javacsharp.aspx特定的「Hello World」的例子在C#