JNI 对象处理 (转)
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,"<init>","()V");
- 以上为构造函数,参数是 "<init>" "()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);
- 返回:
- return obj;
下面是本人练习的例子
- ExList.java
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<ScanResult> list = WifiManager.getScanResults(); System.out.println(list.get(0).ssid); System.out.println(list.get(0).mac); System.out.println(list.get(0).level); } }
- ScanResult.java
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; } }
- WifiManager.java
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<ScanResult> getScanResults(); }
- wifi.cpp
#include <jni.h> #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,"<init>","()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,"<init>","()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,"<init>","()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,"<init>","()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; }
转自:http://leidiqiu.iteye.com/blog/720307
从事图像处理、机器学习、图像识别及人机交互等领域研究及开发,承接各类人工智能、图像处理,视频处理,图像识别算法项目,请联系761551935