JNI——結構體(即java中的類)的傳入與設置——NativeMethod映射表


參考:http://www.cnblogs.com/skywang12345/archive/2013/05/26/3093593.html

     http://www.2cto.com/kf/201501/372701.html

java 類:

package com.skywang.ndk;

public class MyInfo {
	private String  mName;                     
	private int     mAge;
	private float   mHeight;
	
	public String toString(){
		return "mName:"+mName+", mAge:"+mAge+", mHeight:"+mHeight;
	}
}
============================================
Person.java:
 
package com.skywang.ndk;

public class Person {
    
	private String  mName;                     
	private int     mAge;
	private float   mHeight;
	
	public String toString(){
		return "mName:"+mName+", mAge:"+mAge+", mHeight:"+mHeight;
	}

}

  

package com.skywang.ndk;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class NdkParam extends Activity {
	public static final String TAG="skywang--NdkParam";
	public static final String TAG_MY="MY_skywang--NdkParam";
    /** Called when the activity is first created. */
	private Person person=null;
	private MyInfo myinfo = null;
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Log.d(TAG, "on create.");
        person = new Person();
        for (int i=0; i<3; i++) {
	        getPersonInfoByIndex(person, i);
	        Log.d(TAG, "person["+i+"] -- "+person);
        }
        
        Log.d(TAG, "==============================》MyInfo.《==================================");
        myinfo = new MyInfo();
        for (int i=0; i<3; i++) {
        	
        	getMyInfoByIndex(myinfo, i);
	        Log.d(TAG, "myinfo["+i+"] -- "+myinfo);
        }
    }
    
    // jni
    private native int getPersonInfoByIndex(Person person, int index);
    private native int getMyInfoByIndex(MyInfo myinfo, int index);

    static {
    	//System.loadLibrary("ndk_param");
    	System.loadLibrary("ndk_param");
    }
}

  JNI:

頭文件:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>


// 獲取數組的大小
# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
// 指定要注冊的類,對應完整的java類名
#define JNIREG_CLASS "com/skywang/ndk/NdkParam"
#define JNIPAR_CLASS "com/skywang/ndk/Person"

#define JNIPAR_CLASS_MYINFO "com/skywang/ndk/MyInfo"

// 引入log頭文件
#include <android/log.h>  

// log標簽
#define  TAG    "hello_param"
// 定義info信息
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)
// 定義debug信息
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
// 定義error信息
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)

// jfieldID結構體,用於保存類“Person.java”的filedID
struct PersonOffsets
{
    jfieldID    name;
    jfieldID    age;
    jfieldID    height;
} gPersonOffsets;
struct MyInfoOffsets
{
    jfieldID    name;
    jfieldID    age;
    jfieldID    height;
} gMyInfoOffsets;

// 與“Person.java”對應的結構體,用於保存數據,並將數據賦值給Person.java的成員
typedef struct tagPerson
{
	char    mName[10];
	int     mAge;
	float   mHeight;
}Person;
typedef struct tagMyInfo
{
	char    mName[10];
	int     mAge;
	float   mHeight;
}MyInfo;

// 定義了3個Person
static Person gPersons[] = {
	{"skywang", 25, 175},
	{"eman"   , 30, 166},
	{"Dan"    , 51, 172},
};
static MyInfo gMyInfos[] = {
	{"liu", 25, 175},
	{"gang"   , 30, 166},
	{"hong"    , 51, 172},
};

#define GPERSON_NUM NELEM(gPersons)
#define GMYINFO_NUM NELEM(gMyInfos)

  

c文件:


#include "ndk_param.h"


/* 
 * 根據index獲取Person信息。
 * 參數說明:
 * 		env : JNI 接口指針。
 *		claszz : Java 類對象。
 *		person : 輸入參數,java對象
 *		index : 輸入參數,序列號。
 */
JNIEXPORT jint JNICALL 
getPersonInfoByIndex(JNIEnv *env, jobject clazz, jobject person, jint index)
{

	// 若index無效,則直接返回-1。
    if ((int)index<0 || (int)index>=GPERSON_NUM)
        return -1;

	// 將Person數組(gPersons)中的第index個成員賦值給pPerson指針
	Person *pPerson = &gPersons[index];
		
	// 設置java對象person的mName
    jstring name = (*env)->NewStringUTF(env, pPerson->mName);
    (*env)->SetObjectField(env, person, gPersonOffsets.name, name);
	// 設置java對象person的mAge
    (*env)->SetIntField(env, person, gPersonOffsets.age, pPerson->mAge);
	// 設置java對象person的mHeight
    (*env)->SetFloatField(env, person, gPersonOffsets.height, pPerson->mHeight);

	LOGD("%s index-%d  mName:%s, mAge:%d, mHeight:%f\n", 
			__func__, index, pPerson->mName, pPerson->mAge, pPerson->mHeight);

	return 0;
}
JNIEXPORT jint JNICALL getMyInfoByIndex(JNIEnv *env, jobject clazz, jobject myinfo, jint index)
{
	// 若index無效,則直接返回-1。
    if ((int)index<0 || (int)index>=GMYINFO_NUM)
        return -1;
	
	// 將Person數組(gPersons)中的第index個成員賦值給pPerson指針
	MyInfo *pMyInfo = &gMyInfos[index];
	
	// 設置java對象person的mName
    jstring name = (*env)->NewStringUTF(env, pMyInfo->mName);
    (*env)->SetObjectField(env, myinfo, gMyInfoOffsets.name, name);
	
	// 設置java對象person的mAge
    (*env)->SetIntField(env, myinfo, gMyInfoOffsets.age, pMyInfo->mAge);
	// 設置java對象person的mHeight
    (*env)->SetFloatField(env, myinfo, gMyInfoOffsets.height, pMyInfo->mHeight);

	LOGD("%s index-%d  mName:%s, mAge:%d, mHeight:%f\n", 
			__func__, index, pMyInfo->mName, pMyInfo->mAge, pMyInfo->mHeight);

	return 0;
}

// 初始化函數,用於獲取Java中各個成員對應的fieldID。
static void nativeClassInit (JNIEnv *env)
{   
    jclass personClass = (*env)->FindClass(env, JNIPAR_CLASS); 
	jclass myinfoClass = (*env)->FindClass(env, JNIPAR_CLASS_MYINFO);
	
	// 獲取Person的mName成員對應的FieldID,並保存到gPersonOffsets中
    gPersonOffsets.name     = (*env)->GetFieldID(env, personClass, "mName"  , "Ljava/lang/String;"); 
	gMyInfoOffsets.name     = (*env)->GetFieldID(env, myinfoClass, "mName"  , "Ljava/lang/String;"); 
		
	// 獲取Person的mAge成員對應的FieldID,並保存到gPersonOffsets中
    gPersonOffsets.age      = (*env)->GetFieldID(env, personClass, "mAge"   , "I");
	gMyInfoOffsets.age      = (*env)->GetFieldID(env, myinfoClass, "mAge"   , "I");
		
	// 獲取Person的mHeight成員對應的FieldID,並保存到gPersonOffsets中
    gPersonOffsets.height   = (*env)->GetFieldID(env, personClass, "mHeight", "F");
	gMyInfoOffsets.height   = (*env)->GetFieldID(env, myinfoClass, "mHeight", "F");

}

// Java和JNI函數的綁定表
static JNINativeMethod method_table[] = {
	{ "getPersonInfoByIndex", "(Lcom/skywang/ndk/Person;I)I", (void*)getPersonInfoByIndex },//綁定
	{ "getMyInfoByIndex", "(Lcom/skywang/ndk/MyInfo;I)I", (void*)getMyInfoByIndex },//綁定
	
};

// 注冊native方法到java中
static int registerNativeMethods(JNIEnv* env, const char* className,
        JNINativeMethod* gMethods, int numMethods)
{
	jclass clazz;
	clazz = (*env)->FindClass(env, className);
	if (clazz == NULL) {
		return JNI_FALSE;
	}
	if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
		return JNI_FALSE;
	}

	return JNI_TRUE;
}

int register_ndk_param(JNIEnv *env)
{
	nativeClassInit(env);
	// 調用注冊方法
    return registerNativeMethods(env, JNIREG_CLASS,
            method_table, NELEM(method_table));
}

// JNI_OnLoad在jni注冊時,會被回調執行。
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1; 

    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return result;
    }   

    register_ndk_param(env);

	// 返回jni的版本
    return JNI_VERSION_1_4;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM