JNI 返回對象 — 對象數據傳遞(三)

  • Eclipse 新建工程 ExWifi

ScanResult.java 文件

package com.ldq;

public class ScanResult {

	String ssid;
	String mac;
	int level;

	ScanResult() {
	}

}

WifiManager.java 文件

package com.ldq;

public class WifiManager {
	static {
		System.loadLibrary("wifi");
	}

	public native static String test();

	public native static ScanResult getScanResult();

}

 Test.java 文件

package com.ldq;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(WifiManager.test());
		System.out.println(WifiManager.getScanResult().ssid);
		System.out.println(WifiManager.getScanResult().mac);
		System.out.println(WifiManager.getScanResult().level);
	}

}
  • javah -jni com.ldq.WifiManager 生成頭文件 com_ldq_WifiManager.h

com_ldq_WifiManager.h 文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ldq_WifiManager */

#ifndef _Included_com_ldq_WifiManager
#define _Included_com_ldq_WifiManager
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ldq_WifiManager
 * Method:    test
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldq_WifiManager_test
  (JNIEnv *, jclass);

/*
 * Class:     com_ldq_WifiManager
 * Method:    getScanResult
 * Signature: ()Lcom/ldq/ScanResult;
 */
JNIEXPORT jobject JNICALL Java_com_ldq_WifiManager_getScanResult
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif
  • VC++6.0中新建工程 wifi ,選 Win32 Dynamic-Link Library 方式
  • Tools - Options - Directories - Include files 加入 jni.hjni_md.h 的路徑,此處爲
    • C:\Program Files\Java\jdk1.6.0_13\include
    • C:\Program Files\Java\jdk1.6.0_13\include\win32
  • 新建 wifi.cpp 文件

wifi.cpp 文件

#include "com_ldq_WifiManager.h"

/*
 * Class:     com_ldq_WifiManager
 * Method:    test
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldq_WifiManager_test (JNIEnv *env, jclass cls)
{
	return env->NewStringUTF("Hello");
}

/*
 * Class:     com_ldq_WifiManager
 * Method:    getScanResult
 * Signature: ()Lcom/ldq/ScanResult;
 */
JNIEXPORT jobject JNICALL Java_com_ldq_WifiManager_getScanResult (JNIEnv *env, jclass cls)
{
	jclass    m_cls   = env->FindClass("com/ldq/ScanResult");

	jmethodID m_mid   = env->GetMethodID(m_cls,"<init>","()V");
	
	jfieldID  m_fid_1 = env->GetFieldID(m_cls,"ssid","Ljava/lang/String;");
	jfieldID  m_fid_2 = env->GetFieldID(m_cls,"mac","Ljava/lang/String;");
	jfieldID  m_fid_3 = env->GetFieldID(m_cls,"level","I");

	jobject   m_obj   = env->NewObject(m_cls,m_mid);

	                    env->SetObjectField(m_obj,m_fid_1,env->NewStringUTF("AP1"));
						env->SetObjectField(m_obj,m_fid_2,env->NewStringUTF("00-11-22-33-44-55"));
						env->SetIntField(m_obj,m_fid_3,-50);
	return m_obj;
}
  • 上述文件中的代碼是重點
    • 首先獲得類文件,名字爲 "com/ldq/ScanResult" ,不同於Java自身的文件,如 "Ljava/lang/String",前面多了個 "L" ,個人理解爲 Local 的意思,意爲本地庫
    • 再獲得構造函數,注意格式,和一般的引用類的方法不同,名字爲 "<init>" 類型爲 "()V" ,本人在此處耗費了很長時間
    • 獲得類的各個成員變量域,方便後續引用
    • 生成對象,由於參數爲空,所以 NewObject 函數只有兩個參數
    • 設定對象的各個成員變量
    • 返回對象
  • 編譯,將生成的 wifi.dll 文件拷貝到 Eclipse 對應的工程文件根目錄下,此處爲
    • D:\workspace_java\ExWifi
  • Eclipse 下運行,結果爲
運行結果
Hello
AP1
00-11-22-33-44-55
-50

 

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