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

 

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