C#和Java互相調(diào)用的方法小結(jié)
更新時間:2025年04月02日 09:34:42 作者:老胖閑聊
這篇文章主要介紹了C#和Java互相調(diào)用的方法,文中展示了如何在不同編程語言之間實(shí)現(xiàn)互操作,每種語言之間的互操作都有其特定的方法和工具,希望這些示例能夠幫助你更好地理解和實(shí)現(xiàn)跨語言調(diào)用,需要的朋友可以參考下
C# 調(diào)用 Java 類和方法(IKVM / JNI-JNA 橋接)
一、前置條件
- 環(huán)境要求:
- IKVM:安裝 IKVM 工具包(包含
ikvmc
、ikvm
等工具),需要 JDK 和 .NET Framework。 - JNI/JNA:需要 Java JDK(包含
javac
、javah
)和 .NET 的 P/Invoke 支持。
- IKVM:安裝 IKVM 工具包(包含
- 文件準(zhǔn)備:
- Java JAR 包(如
example.jar
)。 - Java 類的完整定義(需公開目標(biāo)類和方法)。
- Java JAR 包(如
二、方法 1:使用 IKVM 橋接
原理:將 Java 字節(jié)碼轉(zhuǎn)換為 .NET 程序集(DLL),直接在 C# 中引用。
實(shí)現(xiàn)步驟:
- 安裝 IKVM:
- 下載 IKVM 二進(jìn)制包并解壓,配置環(huán)境變量。
- 轉(zhuǎn)換 JAR 到 .NET DLL:
ikvmc -target:library example.jar -out:Example.dll
- 在 C# 中引用 DLL:
using IKVM.Runtime; using java.example; // 對應(yīng) Java 包名 public class Program { public static void Main() { // 調(diào)用 Java 類 ExampleClass obj = new ExampleClass(); obj.exampleMethod("Hello from C#"); } }
注意事項(xiàng):
- 確保 Java 類和方法是
public
的。 - 轉(zhuǎn)換過程中可能丟失部分 Java 特性(如動態(tài)代理)。
三、方法 2:使用 JNI/JNA 橋接
原理:通過 JNI 調(diào)用 Java 虛擬機(jī)(JVM),C# 通過 P/Invoke 調(diào)用 JNI 接口。
實(shí)現(xiàn)步驟:
- 編寫 Java 本地接口(JNI):
public class NativeBridge { public static native void callFromCSharp(String message); }
- 生成 C/C++ 頭文件:
javac NativeBridge.java javah -jni NativeBridge
- 生成
NativeBridge.h
。 - 實(shí)現(xiàn) C/C++ 橋接層:
#include <jni.h> #include "NativeBridge.h" JNIEXPORT void JNICALL Java_NativeBridge_callFromCSharp(JNIEnv *env, jclass cls, jstring msg) { const char *cMsg = env->GetStringUTFChars(msg, 0); printf("Java received: %s\n", cMsg); env->ReleaseStringUTFChars(msg, cMsg); }
- 編譯為 DLL:
gcc -shared -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" NativeBridge.c -o NativeBridge.dll
- C# 調(diào)用 DLL:
using System; using System.Runtime.InteropServices; public class Program { [DllImport("NativeBridge.dll")] private static extern void Java_NativeBridge_callFromCSharp(string message); public static void Main() { Java_NativeBridge_callFromCSharp("Hello via JNI"); } }
注意事項(xiàng):
- 需要手動管理 JVM 生命周期(
JNI_CreateJavaVM
)。 - 跨平臺需重新編譯 DLL/SO。
四、常見問題
- IKVM 轉(zhuǎn)換失敗:
- 缺少依賴 JAR 包時,需添加
-reference:other.jar
。
- 缺少依賴 JAR 包時,需添加
- JNI 內(nèi)存泄漏:
- 使用
ReleaseStringUTFChars
釋放資源。
- 使用
- DLL 路徑問題:
- 確保 DLL 在輸出目錄或
PATH
環(huán)境變量中。
- 確保 DLL 在輸出目錄或
五、高級特性
- IKVM 動態(tài)類加載:
var classLoader = new ikvm.runtime.AssemblyClassLoader(typeof(Program).Assembly); var clazz = classLoader.loadClass("java.example.DynamicClass");
- JNI 回調(diào) C# 方法:
- 在 C/C++ 層定義回調(diào)函數(shù),通過 P/Invoke 調(diào)用 C# 委托。
Java 調(diào)用 DLL 的類和方法(JNA)
一、前置條件
- 環(huán)境要求:
- Java 8+,安裝 JNA 庫。
- 文件準(zhǔn)備:
- 目標(biāo) DLL(如
NativeLib.dll
)及其函數(shù)簽名。
- 目標(biāo) DLL(如
二、使用 JNA 方法
原理:通過 JNA 庫直接映射 DLL 函數(shù)到 Java 接口,無需編寫 C 代碼。
實(shí)現(xiàn)步驟:
- 添加 JNA 依賴:
<!-- Maven --> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency>
- 定義 Java 接口:
import com.sun.jna.Library; import com.sun.jna.Native; public interface NativeLib extends Library { NativeLib INSTANCE = Native.load("NativeLib", NativeLib.class); // 映射 DLL 函數(shù) void exampleFunction(String message); int addNumbers(int a, int b); }
- 調(diào)用 DLL 函數(shù):
public class Main { public static void main(String[] args) { NativeLib.INSTANCE.exampleFunction("Hello from Java"); int sum = NativeLib.INSTANCE.addNumbers(3, 4); System.out.println("Sum: " + sum); } }
注意事項(xiàng):
- 函數(shù)名和參數(shù)類型需與 DLL 嚴(yán)格匹配。
- 支持復(fù)雜類型(結(jié)構(gòu)體、指針)需使用
Structure
類。
三、高級特性
回調(diào)函數(shù):
public interface CallbackLib extends Library { interface Callback extends CallbackProxy { void invoke(String result); } void registerCallback(Callback callback); }
結(jié)構(gòu)體映射:
public class Point extends Structure { public int x; public int y; }
四、常見問題
- UnsatisfiedLinkError:
- 檢查 DLL 名稱和路徑,確保 32/64 位一致。
- 參數(shù)類型不匹配:
- 使用
Native.getNativeSize()
調(diào)試類型大小。
- 使用
總結(jié)
- C# 調(diào)用 Java:優(yōu)先使用 IKVM 簡單場景,JNI 用于高性能需求。
- Java 調(diào)用 DLL:JNA 是最簡方案,無需編寫 C 代碼。
- 代碼可維護(hù)性:跨語言調(diào)用需詳細(xì)文檔記錄接口約定。
以上就是C#和Java互相調(diào)用的方法小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于C#和Java互相調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實(shí)現(xiàn)
本文主要介紹了C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07