Android JNI ,将java 实例与c实例绑定

测试条件:

c++ 中存在class TestA,其中含有属性int a。

java 中存在class TestJni,

TestJni.java代码如下:

 1 public class TestJni {
 2 
 3     public native final void setA(int a);
 4     public native final void add(int add);
 5     public native final int getA();
 6     private int mNativeInJavaObj;
 7     
 8     static {
 9         System.loadLibrary("testjni");
10     }
11 }
TestJni中属性mNativeInJavaObj用来绑定c++中TestA的对象实例,有点像一个ID。


com_zcw_soundtouch_TestJni.cpp代码如下:
 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 #include <android/log.h>
 4 
 5 #include "testclassa.h"
 6 /* Header for class com_zcw_soundtouch_TestJni */
 7 
 8 #define LOGV(...)   __android_log_print((int)ANDROID_LOG_INFO, "SOUNDTOUCH", __VA_ARGS__)
 9 //#define LOGV(...)
10 
11 // ----------------------------------------------------------------------------
12 
13 struct fields_t {
14     jclass    testAClass;
15     jfieldID    context;
16 };
17 static fields_t fields;
18 
19 //static Mutex sLock;
20 
21 // ----------------------------------------------------------------------------
22 
23 
24 #ifndef _Included_com_zcw_soundtouch_TestJni
25 #define _Included_com_zcw_soundtouch_TestJni
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 void persistence(JNIEnv * env, jobject thiz){
30     LOGV("called persistence");
31     /*
32     fields.testAClass = env->FindClass("");
33     fields.context = 
34         env->GetFieldID(fields.testAClass,
35                         "mNativeInJavaObj", "I");
36     */
37     if(NULL==fields.context){
38         fields.testAClass = env->GetObjectClass(thiz);
39         fields.context = 
40         env->GetFieldID(fields.testAClass,
41                         "mNativeInJavaObj", "I");
42         
43     }
44     int value = env->GetIntField(thiz, fields.context);
45     if(0!=value){
46         LOGV("class TestA is eixts");
47         return ;
48     }
49     LOGV("class TestA is not eixts");
50     TestA * testA = new TestA();
51     testA->setA(10);
52     env->SetIntField(thiz,fields.context, (int)testA);
53 }
54 /*
55  * Class:     com_zcw_soundtouch_TestJni
56  * Method:    setA
57  * Signature: (I)V
58  */
59 JNIEXPORT void JNICALL Java_com_zcw_soundtouch_TestJni_setA
60   (JNIEnv *env, jobject thiz, jint value)
61 {
62     persistence(env,thiz);
63     TestA* testA = (TestA*)env->GetIntField(thiz, fields.context);
64     testA->setA((int)value);
65 }
66 
67 /*
68  * Class:     com_zcw_soundtouch_TestJni
69  * Method:    add
70  * Signature: (I)V
71  */
72 JNIEXPORT void JNICALL Java_com_zcw_soundtouch_TestJni_add
73   (JNIEnv *env, jobject thiz, jint value)
74 {
75     persistence(env,thiz);
76     TestA* testA = (TestA*)env->GetIntField(thiz, fields.context);
77     testA->addA((int)value);
78     
79 }
80 
81 /*
82  * Class:     com_zcw_soundtouch_TestJni
83  * Method:    getA
84  * Signature: ()I
85  */
86 JNIEXPORT jint JNICALL Java_com_zcw_soundtouch_TestJni_getA
87   (JNIEnv *env, jobject thiz )
88 {
89     persistence(env,thiz);
90     TestA* testA = (TestA*)env->GetIntField(thiz, fields.context);
91     
92     return testA->getA();
93 }
94 
95 #ifdef __cplusplus
96 }
97 #endif
98 #endif

testclassa.h

 1 #include<stdio.h>
 2 
 3 
 4 class TestA{
 5 private:
 6     int a ;
 7 
 8 public:
 9     TestA();
10     ~TestA();
11     void setA(int avalue);
12     void addA(int add);
13     int getA();
14 
15 };

testclassa.cpp

 1 #include<stdio.h>
 2 #include "testclassa.h"
 3 
 4 TestA::TestA(){}
 5 TestA::~TestA(){}
 6 
 7 
 8 void TestA::setA(int avalue)
 9 {
10     a = avalue;
11 }
12 
13 void TestA::addA(int add)
14 {
15     a+=add;
16 }
17 
18 int TestA::getA()
19 {
20     return a;
21 }

java测试代码:

 1 Log.e(TAG, "start load jni");
 2         {
 3             TestJni testJni = new TestJni();
 4             Log.e(TAG, "loaded jni");
 5             testJni.setA(100);
 6             Log.e(TAG, "setted value ");
 7             testJni.add(2912);
 8             int value = testJni.getA();
 9             Log.e(TAG, "after add:a="+value);
10         }
11         Log.e(TAG, "===============");
12         {
13             TestJni testJni = new TestJni();
14             Log.e(TAG, "loaded jni");
15             testJni.setA(257);
16             Log.e(TAG, "setted value ");
17             testJni.add(212);
18             int value = testJni.getA();
19             Log.e(TAG, "after add:a="+value);
20         }

打印结果:

 1 10-21 12:52:41.057: E/Main2Activity(13677): loaded jni
 2 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
 3 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is not eixts
 4 10-21 12:52:41.057: E/Main2Activity(13677): setted value 
 5 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
 6 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is eixts
 7 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
 8 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is eixts
 9 10-21 12:52:41.057: E/Main2Activity(13677): after add:a=3012
10 10-21 12:52:41.057: E/Main2Activity(13677): ===============
11 10-21 12:52:41.057: E/Main2Activity(13677): loaded jni
12 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
13 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is not eixts
14 10-21 12:52:41.057: E/Main2Activity(13677): setted value 
15 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
16 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is eixts
17 10-21 12:52:41.057: I/SOUNDTOUCH(13677): called persistence
18 10-21 12:52:41.057: I/SOUNDTOUCH(13677): class TestA is eixts
19 10-21 12:52:41.057: E/Main2Activity(13677): after add:a=469

 

原文地址:https://www.cnblogs.com/zhouchanwen/p/3380393.html