JNI——结构体(即java中的类)的传入与设置——NativeMethod映射表

参考: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;

}

  

时间: 2024-10-08 19:17:54

JNI——结构体(即java中的类)的传入与设置——NativeMethod映射表的相关文章

关于java中ReentrantLock类的源码分析以及总结与例子

一,官方描述 关于ReentrantLock的官方描述,英文的就不贴出来了,这里我只贴出我自己翻译的描述: reentrant是一个跟synchronized具有相同行为和语义的持有锁来访问方法和语句的互斥锁,但是reentrant还拥有被扩展的能力. ReentrantLock会被线程拥有并且持续锁定,不会解锁.线程调用lock()方法返回后,则成功持有锁,否则这个锁正在被另一个线程所持有,只能等待另一个线程释放锁,如果当前线程拥有了锁,则调用lock()方法会立即返回,这个状态可以通过isH

在java中String类为什么要设计成final?

大神链接:在java中String类为什么要设计成final? - 程序员 - 知乎 我进行了重新排版,并且更换了其中的一个例子,让我们更好理解. String很多实用的特性,比如说"不可变性",是工程师精心设计的艺术品!艺术品易碎!用final就是拒绝继承,防止世界被熊孩子破坏,维护世界和平! 1. 什么是不可变? String不可变很简单,如下图,给一个已有字符串"abcd"第二次赋值成"abcedl",不是在原内存地址上修改数据,而是重新指

逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式

一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合 2.在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类. 3. 结构体可以被声明为变量.指针或数组等,用以实现较复杂的数据结构.结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问. 高级代

C++ 的向量结构结合了Java中数组和向量两者的优点

C++ 的向量结构结合了Java中数组和向量两者的优点.一个C++ 的向量可以方便的被访问,其容量又可以动态的增长.如果 T 是任意类型,则 vector<T> 是一个元素为 T 类型的动态数组.下面的语句 vector<int> a; 产生一个初始为空的向量.而语句 vector<int> a(100); 生成一个初始有100个元素的向量.你可以使用push_back 函数来添加元素: a.push_back(n); 调用 a.pop_back() 从a中取出最后一个

hadoop中Text类 与 java中String类的区别

hadoop 中 的Text类与java中的String类感觉上用法是相似的,但两者在编码格式和访问方式上还是有些差别的,要说明这个问题,首先得了解几个概念: 字符集: 是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国家文字.标点符号.图形符号.数字等.例如 unicode就是一个字符集,它的目标是涵盖世界上所有国家的文字和符号: 字符编码:是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对.即在符号集

Java中String类学习总结

java中String类的使用频率非常高,本人在学习此模块时,认为下列几点知识值得注意: 一.String是不可变对象 java.lang.String类使用了final修饰,不能被继承.Java程序中的所有字面值,即双引号括起的字符串,如"abc",都是作为String类的实例实现的.String是常量,其对象一旦构造就不能再被改变.换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容.而最

【转载】Java中String类的方法及说明

转载自:http://www.cnblogs.com/YSO1983/archive/2009/12/07/1618564.html String : 字符串类型 一.构造函数     String(byte[ ] bytes):通过byte数组构造字符串对象.     String(char[ ] value):通过char数组构造字符串对象.     String(Sting original):构造一个original的副本.即:拷贝一个original.     String(Strin

java中Color类的简单总结

java中Color类的简单总结 1.颜色的常识 任何颜色都是由三原色组成(RGB),JAVA中支持224为彩色,即红绿蓝分量取值 介于0-255之间(8位表示) 2.Color类中的常量 public final static Color black = new Color(0,0,0); public final static Color bule = new Color(0,0,255); . . 有很多这样的常量,可供我们直接类名去调用而不需要去实例化. 3.Color中的构造函数 pu

Java中Arrays类的两个方法:deepEquals和equals

deepEquals和equals是Java中Arrays类的两个静态方法,可是它们之间有什么样的区别呢? 代码一. import java.util.Arrays; public class Test { public static void main(String[] args) { String[][] name1 = {{ "G","a","o" },{ "H","u","a",