在Java平台中,JNI(Java Native Interface)技术允许开发者将Java代码与其他语言编写的代码相结合,如C++、Delphi和C#。本文将展示如何从C#客户端调用Java方法。
通过JNI,可以在新的C#应用程序中重用之前用Java编写的现有库/类。这意味着不必放弃用Java编写的旧代码,也无需在C#中重新编写相同的功能。
在JNI中,了解字段描述符是非常重要的。在测试框架中,当调用一个接受字符串参数的Java方法时,会传入"Ljava/lang/String;"。这代表了Java编程语言中的字段类型。例如,如果想表示一个int字段,会使用"I",一个float字段会是"F",一个boolean字段会是"Z"等。
以下表格描述了Java编程语言中的原始类型以及它们在JNI中的对应类型。所有以L开头的字段描述符都被视为对象(注意:字符串作为对象传递),并且必须以";"字符结尾。数组类型总是以"["字符开头。
JNI字段描述符 | Java语言类型 |
---|---|
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
Ljava/lang/String; | string |
[Ljava/lang/Object; | object[] |
方法描述符使用字段描述符并描述Java方法的结构。在方法描述符中,字段描述符之间没有空格。以下表格描述了Java方法声明和对应的JNI描述符。JNI方法描述符用于从C#通过JNI调用Java方法。
Java方法声明 | JNI方法描述符 |
---|---|
String foo(); | ()Ljava/lang/String; |
Void bar(int I, bool b); | (IZ)V |
以下是从.NET GUI应用程序调用Java代码的示例。一旦设置了对位于代码下载部分的JNI程序集的引用,就可以开始调用Java方法了。首先需要做的是创建一个字典对象,它将包含要传递给Java虚拟机的所有参数。在以下示例中,设置了类路径,这将告诉JVM在哪里查找类和包。
Java
private Dictionary<string, string> jvmParameters = new Dictionary<string, string>();
jvmParameters.Add("-Djava.class.path", Location of the java class);
一旦JVM参数被分配给字典对象,就可以创建一个JavaNativeInterface的实例。创建后,需要调用LoadJVM方法,并传入JVM参数,这将加载Java虚拟机。加载后,用户可以调用方法来实例化Java对象(注意:使用InstantiateJavaObject方法不是必须的,因为用户可能只想调用静态方法,在这种情况下,不需要调用这个方法;然而,它不会造成任何伤害)。
Java Java = new JavaNativeInterface();
Java.LoadVM(jvmParameters, false);
Java.InstantiateJavaObject(Name of the java class excluding the extension);
一旦JVM加载并实例化了一个类,用户就可以调用他们想要的任何方法。首先创建一个对象列表,它将包含要传递给Java方法的所有参数。由于它是一个对象列表,它可以包含不同类型的参数,因为所有东西都继承自对象。
C#
List<object> olParameters = new List<object>();
olParameters.Add(Value of the parameter to be passed to the java method);
接下来,只需调用泛型方法CallMethod,传入Java方法的返回类型作为模板类型。在以下示例中,调用了CallMethod<string>,这意味着想要调用的Java方法的返回类型是字符串。
C#
Java.CallMethod<string>(
"AddTwoNumbers",
"(IILjava/lang/String;)I", olParameters);