解壓縮後, 會得到三個資料夾:
- bin: 內有 proxygen.exe 執行檔, 用來產生Java與C#程式間溝通用的Proxy.
- lib: 包含將來執行時要用到的 .dll 與 .jar 檔.
- samples: 顧名思義, 放的是 jni4net 的範例程式碼.
Step 1: 利用 Visual Studio 建立一個名為 CSharpLib 的 C# 函式庫專案, 並簡單寫一個MainTable.cs 程式如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CSharpLib { public class MainTable { public string GetHello(string name) { return string.Format("Hello, {0}", name); } public HelloModel GetHelloObject() { HelloModel m = new HelloModel(); m.Hello = "hello"; m.World = "world"; return m; } } public class HelloModel { public string Hello { get; set; } public string World { get; set; } } }這程式簡單地說明如下:
- class HelloModel: 為了後續驗證 java 程式對 C# Model 的使用.
- GetHello(): 輸入一個字串參數, 用 string.Format() 包裝後回傳回去.
- GetHelloObject(): 設定一個 HelloModel 物件的 Hello 跟 World 兩個屬性後, 再將此物件回傳.
Step 3: 利用 proxygen.exe 產生 Proxy 相關函式庫.
- 開啟一個 cmd, 並輸入以下指令:
"F:\Software\jni4net-0.8.8.0-bin\bin\proxygen.exe" "C:\test\CSharpLib.dll" -wd "C:\test2"
參數1是 proxygen.exe 所在位置, 參數2是 CSharpLib.dll 所在位置, 最後的 -wd path 是指定輸出目錄. - 執行完畢, 會在 C:\test2\內看到2個目錄, 2個檔案:
clr\
jvm\
build.cmd
CSharpLib.proxygen.xml
- 如果執行 build.cmd 發生 "'csc' 不是內部或外部命令、可執行的程式或批次檔。"的錯誤, 可到 C:\Program Files (x86)\MSBuild\12.0\Bin\ 或 C:\Program Files (x86)\MSBuild\12.0\Bin\amd64\ 找到 csc.exe, 將 build.cmd 內的 csc 改為"C:\Program Files (x86)\MSBuild\12.0\Bin\csc.exe".
- 如果執行 proxygen.exe 後, 你有搬移一些檔案, 可在 build.cmd 內再確認一次檔案路徑是否都正確.
Step 6: 開發環境的設定(Eclipse):
- 建立一個名為 Jni4NetTest 的 Java Project, 並加入必要的 jar 參考 :
在 Jni4NetTest 專案上按右鍵 –> [Build Path] –> [Configure Build Path…] –> 切到 [Libraries] 頁籤 –> 按下 [Add External JARs…] –> 將 jni4net.j-0.8.8.0.jar 與 CSharpLib.j4n.jar 加到專案的參考. - 在專案內新增一個 lib 目錄, 並加入必要的 dll 檔案:
將 CSharpLib.dll, CSharpLib.j4n.dll, jni4net.n-0.8.8.0.dll, jni4net.n.w64.v40-0.8.8.0.dll 加入該資料夾.
至於 jni4net-0.8.8.0-bin\lib\ 裡的 jni4net.n.w32.v20-0.8.8.0.dll, jni4net.n.w32.v40-0.8.8.0.dll, jni4net.n.w64.v20-0.8.8.0.dll, jni4net.n.w64.v40-0.8.8.0.dll 四個檔案要選哪一個, 就要看當初建 C# 專案時, 是選什麼 Framework, 以及是在 32/64 位元環境執行. - 新增一個測試用的 JniTest.java, 程式碼如下:
package com.test; import java.io.File; import java.io.IOException; import net.sf.jni4net.Bridge; import csharplib.HelloModel; import csharplib.MainTable; public class JniTest { public static void main(String[] args) { // TODO Auto-generated method stub try { Bridge.setVerbose(true); Bridge.init(new File( "C:/Users/yilin/workspace/Jni4NetTest/lib/jni4net.n.w64.v40-0.8.8.0.dll")); Bridge.LoadAndRegisterAssemblyFrom(new File( "C:/Users/yilin/workspace/Jni4NetTest/lib/CSharpLib.j4n.dll")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } MainTable m = new MainTable(); HelloModel hm = m.GetHelloObject(); System.out.println(m.GetHello("test")); System.out.println(hm.getHello()); System.out.println(hm.getWorld()); } }
- 完成後的專案結構圖如下:
- 要注意 C# 函式庫轉換到 Java 後的 namespace 大小寫有改變。
- 若執行時出現 "Exception in thread "main" java.lang.UnsatisfiedLinkError:" , 表示程式未正確找到相關的 dll 檔, 解決方式是在 Bridge.init() 時指定一個完整路徑的 jni4net.n.w64.v40-0.8.8.0.dll 檔案.
- 程式中, 有關 dll 的路徑指定, 用絕對路徑是較無問題的. 若擔心程式寫死路徑不好, 可以考慮放到其他設定檔或資料庫內.
- 一開始使用時, 可先設定 Bridge.setVerbose(true); , 確認 clr.version 是 v2或v4, 以及 clr.arch 是 32/64 bit, 以利確認用哪一版正確的 jni4net.n.w32.v20-0.8.8.0.dll, jni4net.n.w32.v40-0.8.8.0.dll, jni4net.n.w64.v20-0.8.8.0.dll, jni4net.n.w64.v40-0.8.8.0.dll
Generating Proxies
沒有留言:
張貼留言