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

 
short S 
int I 
long  
float  

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;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章