JNI 的基本问题就是解决 Java 和 C++ 代码互相调用的通信问题,在 C++ 代码编写过程中最大的问题莫过于适应其中的代码编写规则,C++调用或是返回的内容必须遵守 JVM 和 C++ 代码的通信规则。
C++ 调用 Java 的一般步骤如下:
- 获得类:
- jclass cls = env->FindClass("com/ldq/Student");
- cls 可认为是类的句柄
- "com/ldq/Student" 就是类文件,注意不能用 "com.ldq.Student"
- 获得方法:
- jmethodID mid = env->GetMethodID(cls,"","()V");
- 以上为构造函数,参数是 "" "()V"
- jmethodID mid = env->GetMethodID(cls,"getAge","()I");
- 以上为类的方法,第一个参数是类句柄,第二个参数是方法名字,第三个参数是签名标识
Java类型 |
符号 |
boolean |
Z |
byte |
B |
char |
C |
short |
S |
int |
I |
long |
L |
float |
F |
double |
D |
void |
V |
objects对象 |
Lfully-qualified-class-name; L类名; |
Arrays数组 |
[array-type [数组类型 |
methods方法 |
(argument-types)return-type(参数类型)返回类型 |
- 获得对象:
- jobject obj=env->NewObject(cls,mid);
- 以上便获得了一个对象的句柄
- 获得对象成员变量:
- jfieldID fid=env->GetFieldID(cls,"age","I");
- 以上和获得类方法差不多
- 操作成员变量:
- jint a=env->GetIntField(obj,mid);
- age=age+10;
- env->SetIntField(obj,fid,a);
- 返回:
下面是本人练习的例子
- package com.ldq.list;
-
- import java.util.List;
-
- public class ExList {
-
-
-
-
- public static void main(String[] args) {
-
- System.out.println("-------WifiManager.test()");
- System.out.println(WifiManager.test());
-
- System.out.println("-------WifiManager.testArray()");
- String[] s1 = WifiManager.testArray();
- for (int i = 0; i < s1.length; i++) {
- System.out.println(s1[i]);
- }
-
- System.out.println("-------WifiManager.testObject()");
- System.out.println(WifiManager.testObject().ssid);
- System.out.println(WifiManager.testObject().mac);
- System.out.println(WifiManager.testObject().level);
-
- System.out.println("-------WifiManager.getScanResultsA()");
- ScanResult[] s2 = WifiManager.getScanResultsA();
- for (int i = 0; i < s2.length; i++) {
- System.out.println(s2[i].ssid);
- System.out.println(s2[i].mac);
- System.out.println(s2[i].level);
- }
-
- System.out.println("-------WifiManager.getScanResults()");
- List list = WifiManager.getScanResults();
- System.out.println(list.get(0).ssid);
- System.out.println(list.get(0).mac);
- System.out.println(list.get(0).level);
-
- }
- }
package com.ldq.list;
import java.util.List;
public class ExList {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("-------WifiManager.test()");
System.out.println(WifiManager.test());
System.out.println("-------WifiManager.testArray()");
String[] s1 = WifiManager.testArray();
for (int i = 0; i < s1.length; i++) {
System.out.println(s1[i]);
}
System.out.println("-------WifiManager.testObject()");
System.out.println(WifiManager.testObject().ssid);
System.out.println(WifiManager.testObject().mac);
System.out.println(WifiManager.testObject().level);
System.out.println("-------WifiManager.getScanResultsA()");
ScanResult[] s2 = WifiManager.getScanResultsA();
for (int i = 0; i < s2.length; i++) {
System.out.println(s2[i].ssid);
System.out.println(s2[i].mac);
System.out.println(s2[i].level);
}
System.out.println("-------WifiManager.getScanResults()");
List
list = WifiManager.getScanResults();
System.out.println(list.get(0).ssid);
System.out.println(list.get(0).mac);
System.out.println(list.get(0).level);
}
}
- package com.ldq.list;
-
- public class ScanResult {
- String ssid;
- String mac;
- int level;
-
- public ScanResult() {
- }
-
- public ScanResult(String ssid, String mac, int level) {
- this.ssid = ssid;
- this.mac = mac;
- this.level = level;
- }
- }
package com.ldq.list;
public class ScanResult {
String ssid;
String mac;
int level;
public ScanResult() {
}
public ScanResult(String ssid, String mac, int level) {
this.ssid = ssid;
this.mac = mac;
this.level = level;
}
}
- package com.ldq.list;
-
- import java.util.List;
-
- public class WifiManager {
-
- static {
- System.loadLibrary("wifi");
- }
-
- public native static String test();
-
- public native static String[] testArray();
-
- public native static ScanResult testObject();
-
- public native static ScanResult[] getScanResultsA();
-
- public native static List getScanResults();
- }
package com.ldq.list;
import java.util.List;
public class WifiManager {
static {
System.loadLibrary("wifi");
}
public native static String test();
public native static String[] testArray();
public native static ScanResult testObject();
public native static ScanResult[] getScanResultsA();
public native static List getScanResults();
}
- #include
- #include "com_ldq_list_WifiManager.h"
-
-
-
-
-
-
- JNIEXPORT jstring JNICALL Java_com_ldq_list_WifiManager_test (JNIEnv *env, jclass cls)
- {
- return env->NewStringUTF("hello");
- }
-
-
-
-
-
-
- JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_testArray (JNIEnv *env, jclass cls)
- {
- jobjectArray ret;
- int i;
-
- char *message[5]= {"first",
- "second",
- "third",
- "fourth",
- "fifth"};
-
- ret= (jobjectArray)env->NewObjectArray(5,
- env->FindClass("java/lang/String"),
- env->NewStringUTF(""));
-
- for(i=0;i<5;i++) {
- env->SetObjectArrayElement(
- ret,i,env->NewStringUTF(message[i]));
- }
- return(ret);
-
- }
-
-
-
-
-
-
- JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_testObject (JNIEnv *env, jclass cls)
- {
- jclass m_cls = env->FindClass("com/ldq/list/ScanResult");
- jmethodID mid = env->GetMethodID(m_cls,"","()V");
- jobject obj = env->NewObject(m_cls,mid);
-
- jfieldID fid_ssid = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");
- jfieldID fid_mac = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");
- jfieldID fid_level = env->GetFieldID(m_cls,"level","I");
-
- env->SetObjectField(obj,fid_ssid,env->NewStringUTF("AP1"));
- env->SetObjectField(obj,fid_mac,env->NewStringUTF("00-11-22-33-44-55"));
- env->SetIntField(obj,fid_level,-66);
- return obj;
- }
-
-
-
-
-
-
- JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_getScanResultsA (JNIEnv *env, jclass cls)
- {
- jclass cls_array=env->FindClass("java/lang/Object");
- jobjectArray obj_array=env->NewObjectArray(2,cls_array,0);
-
- jclass cls_obj = env->FindClass("com/ldq/list/ScanResult");
- jmethodID m = env->GetMethodID(cls_obj,"","()V");
-
- jfieldID fid_ssid = env->GetFieldID(cls_obj,"ssid","Ljava/lang/String;");
- jfieldID fid_mac = env->GetFieldID(cls_obj,"mac","Ljava/lang/String;");
- jfieldID fid_level = env->GetFieldID(cls_obj,"level","I");
-
- for(int i=0;i<2;i++)
- {
- jobject obj=env->NewObject(cls_obj,m);
-
- jobject o1=env->NewStringUTF("AP2");
- env->SetObjectField(obj,fid_ssid,o1);
-
- jobject o2=env->NewStringUTF("22-22-22-22-22-22");
- env->SetObjectField(obj,fid_mac,o2);
-
- env->SetIntField(obj,fid_level,-66);
-
- env->SetObjectArrayElement(obj_array,i,obj);
- }
- return obj_array;
- }
-
-
-
-
-
-
- JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_getScanResults (JNIEnv *env, jclass cls)
- {
- jclass m_cls_list = env->FindClass("java/util/ArrayList");
- jmethodID m_mid_list = env->GetMethodID(m_cls_list,"","()V");
- jobject m_obj_list = env->NewObject(m_cls_list,m_mid_list);
-
- jmethodID m_mid_add = env->GetMethodID(m_cls_list,"add","(Ljava/lang/Object;)Z");
-
- jclass m_cls_result = env->FindClass("com/ldq/list/ScanResult");
- jmethodID m_mid_result = env->GetMethodID(m_cls_result,"","()V");
- jobject m_obj_result = env->NewObject(m_cls_result,m_mid_result);
-
- jfieldID m_fid_1 = env->GetFieldID(m_cls_result,"ssid","Ljava/lang/String;");
- jfieldID m_fid_2 = env->GetFieldID(m_cls_result,"mac","Ljava/lang/String;");
- jfieldID m_fid_3 = env->GetFieldID(m_cls_result,"level","I");
-
- env->SetObjectField(m_obj_result,m_fid_1,env->NewStringUTF("AP6"));
- env->SetObjectField(m_obj_result,m_fid_2,env->NewStringUTF("66-66-66-66-66-66"));
- env->SetIntField(m_obj_result,m_fid_3,-66);
-
- env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result);
-
- return m_obj_list;
- }
#include
#include "com_ldq_list_WifiManager.h"
/*
* Class: com_ldq_list_WifiManager
* Method: test
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_ldq_list_WifiManager_test (JNIEnv *env, jclass cls)
{
return env->NewStringUTF("hello");
}
/*
* Class: com_ldq_list_WifiManager
* Method: testArray
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_testArray (JNIEnv *env, jclass cls)
{
jobjectArray ret;
int i;
char *message[5]= {"first",
"second",
"third",
"fourth",
"fifth"};
ret= (jobjectArray)env->NewObjectArray(5,
env->FindClass("java/lang/String"),
env->NewStringUTF(""));
for(i=0;i<5;i++) {
env->SetObjectArrayElement(
ret,i,env->NewStringUTF(message[i]));
}
return(ret);
}
/*
* Class: com_ldq_list_WifiManager
* Method: testObject
* Signature: ()Lcom/ldq/list/ScanResult;
*/
JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_testObject (JNIEnv *env, jclass cls)
{
jclass m_cls = env->FindClass("com/ldq/list/ScanResult");
jmethodID mid = env->GetMethodID(m_cls,"","()V");
jobject obj = env->NewObject(m_cls,mid);
jfieldID fid_ssid = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");
jfieldID fid_mac = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");
jfieldID fid_level = env->GetFieldID(m_cls,"level","I");
env->SetObjectField(obj,fid_ssid,env->NewStringUTF("AP1"));
env->SetObjectField(obj,fid_mac,env->NewStringUTF("00-11-22-33-44-55"));
env->SetIntField(obj,fid_level,-66);
return obj;
}
/*
* Class: com_ldq_list_WifiManager
* Method: getScanResultsA
* Signature: ()[Lcom/ldq/list/ScanResult;
*/
JNIEXPORT jobjectArray JNICALL Java_com_ldq_list_WifiManager_getScanResultsA (JNIEnv *env, jclass cls)
{
jclass cls_array=env->FindClass("java/lang/Object");
jobjectArray obj_array=env->NewObjectArray(2,cls_array,0);
jclass cls_obj = env->FindClass("com/ldq/list/ScanResult");
jmethodID m = env->GetMethodID(cls_obj,"","()V");
jfieldID fid_ssid = env->GetFieldID(cls_obj,"ssid","Ljava/lang/String;");
jfieldID fid_mac = env->GetFieldID(cls_obj,"mac","Ljava/lang/String;");
jfieldID fid_level = env->GetFieldID(cls_obj,"level","I");
for(int i=0;i<2;i++)
{
jobject obj=env->NewObject(cls_obj,m);
jobject o1=env->NewStringUTF("AP2");
env->SetObjectField(obj,fid_ssid,o1);
jobject o2=env->NewStringUTF("22-22-22-22-22-22");
env->SetObjectField(obj,fid_mac,o2);
env->SetIntField(obj,fid_level,-66);
env->SetObjectArrayElement(obj_array,i,obj);
}
return obj_array;
}
/*
* Class: com_ldq_list_WifiManager
* Method: getScanResults
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_com_ldq_list_WifiManager_getScanResults (JNIEnv *env, jclass cls)
{
jclass m_cls_list = env->FindClass("java/util/ArrayList");
jmethodID m_mid_list = env->GetMethodID(m_cls_list,"","()V");
jobject m_obj_list = env->NewObject(m_cls_list,m_mid_list);
jmethodID m_mid_add = env->GetMethodID(m_cls_list,"add","(Ljava/lang/Object;)Z");
jclass m_cls_result = env->FindClass("com/ldq/list/ScanResult");
jmethodID m_mid_result = env->GetMethodID(m_cls_result,"","()V");
jobject m_obj_result = env->NewObject(m_cls_result,m_mid_result);
jfieldID m_fid_1 = env->GetFieldID(m_cls_result,"ssid","Ljava/lang/String;");
jfieldID m_fid_2 = env->GetFieldID(m_cls_result,"mac","Ljava/lang/String;");
jfieldID m_fid_3 = env->GetFieldID(m_cls_result,"level","I");
env->SetObjectField(m_obj_result,m_fid_1,env->NewStringUTF("AP6"));
env->SetObjectField(m_obj_result,m_fid_2,env->NewStringUTF("66-66-66-66-66-66"));
env->SetIntField(m_obj_result,m_fid_3,-66);
env->CallBooleanMethod(m_obj_list,m_mid_add,m_obj_result);
return m_obj_list;
}