参考:http://www.cnblogs.com/skywang12345/archive/2013/05/26/3093593.html
java 类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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;
}
} |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
头文件: #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) |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
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;
} |