概述
本文主要Java与C++之间的对象传递与取值。包括传递Java对象、返回Java对象、修改Java对象、以及性能对比。
通过JNIEnv完成数据转换
Java对象是存在于JVM虚拟机中的,而C++是脱离JVM而运行的,如果在C++中访问和使用Java中的对象,必然会使用JNIEnv这个桥梁。其实通过下面的代码很容易看出,这种访问方式和Java中的反射十分雷同。
这里定义一个简单Java对象用于下文测试:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.example.wastrel.hellojni; <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/** * Created by wastrel on 2016/8/24. */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Bean</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String msg; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Bean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg=msg; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what=what; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">getMsg</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> msg; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setMsg</span>(String msg) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg = msg; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getWhat</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> what; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setWhat</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what = what; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:"</span>+msg+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">";What:"</span>+what; } } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>
从C++中创建一个Java对象并返回
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Java中的native方法声明</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> Bean <span class="hljs-title" style="box-sizing: border-box;">newBean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法实现</span> JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span> (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">msg</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span> j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在实际应用中应该确保你的class、method、field存在。减少此类判断。</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL) { LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find class"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取构造函数。构造函数的返回值是void,因此这里方法签名最后为V</span> jmethodID bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL) { LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find init function"</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL; } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然后调用构造函数获得bean</span> j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,msg,what)</span>;</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean; } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>
注:如果提示找不到NULL 请
include<stddef.h>
C++中解析Java对象
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native声明</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> String <span class="hljs-title" style="box-sizing: border-box;">getString</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-c++ hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法实现</span> JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getString (JNIEnv <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*env</span>, jobject obj,jobject bean){ jclass bean_clz=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这部分是通过get函数去获取对应的值 </span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// jmethodID bean_getmsg=env->GetMethodID(bean_clz,"getMsg","()Ljava/lang/String;");</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// jmethodID bean_getwhat=env->GetMethodID(bean_clz,"getWhat","()I");</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// jstring jmsg=(jstring)env->CallObjectMethod(bean,bean_getmsg);</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// jint what=env->CallIntMethod(bean,bean_getwhat);</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这部分是通过类的成员变量直接取获取值,你可能注意到在Java中定义的变量都是private修饰的,但在反射的调用下是毫无作用的。</span> jfieldID bean_fmsg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>); jfieldID bean_fwhat=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>); jstring jmsg=(jstring)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetObjectField(bean,bean_fmsg); jint what=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetIntField(bean,bean_fwhat); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将拿到的值拼装一个String返回回去</span> const char * msg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetStringUTFChars(jmsg,NULL); char <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*str</span>=new char[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>]; sprintf(str,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:%s;What:%d(From C++)"</span>,msg,what); jstring rs=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->NewStringUTF(str); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span> []str; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->ReleaseStringUTFChars(jmsg,msg); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> rs; } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>
注:sprintf函数包含在stdio.h头文件中
C++中修改Java对象属性值
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native声明</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">ModifyBean</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++实现</span> JNIEXPORT <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> JNICALL Java_com_example_wastrel_hellojni_HelloJNI_ModifyBean (JNIEnv <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>env, jobject obj,jobject bean){ jclass bean_clz<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>); jfieldID bean_fmsg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>); jfieldID bean_fwhat<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>); jstring msg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>NewStringUTF(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Modify in C++"</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//重新设置属性</span> env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetObjectField(bean,bean_fmsg,msg); env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetIntField(bean,bean_fwhat,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>; } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
结果图
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java中调用代码</span> HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI(); Bean bean=helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from C++ bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>); tv.setText(bean.toString()); bean=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from Java bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>); tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+helloJNI.getString(bean)); helloJNI.ModifyBean(bean); tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+bean.toString());</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>
Java中new Object和C++中new Object的性能对比
下面我们通过一个测试函数来比较通过两种方式的性能,这里可以毫无疑问的告诉你,Java一定比C++的快。那么这个对比的意义就在于,使用C++创建Java对象的时候会不会造成不可接受的卡顿。
这里使用的测试机是华为Mate7,具体硬件配置可自行百度。
测试函数如下:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Test(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> startTime=System.currentTimeMillis(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> endTime=System.currentTimeMillis(); Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>); HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI(); startTime=System.currentTimeMillis(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++) { helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i); } endTime=System.currentTimeMillis(); Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++ new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
测试结果:
<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 38ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 6ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 79ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 56ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 338ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 60ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 687ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
通过结果可以看出,通过C++来new对象比Java慢了足足10倍左右。但是从时间上来讲,如果只是在C++中new一个Java对象,几个微秒的时间差距完全是可以忽略不计的。
也许有人就会说,C++慢那么多是因为每次都在FindClass,GetMethodId,而在程序运行过程中这两个值是不会改变的。听起来确实有这样一个原因,下面我们将C++中的代码稍作修改缓存jclass和jmethodId。
修改后的newBean函数:
<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用静态变量缓存</span> static j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NULL</span>;</span> static jmethodID bean_init=NULL; JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span> (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">str</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL) { j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">_bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span> bean_clz=(jclass)env->NewGlobalRef(_bean_clz); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取构造函数。构造函数的返回值是void,因此这里方法签名最后为V</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL) { bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然后调用构造函数获得bean</span> j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,str,what)</span>;</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>
你可能发现了缓存方法ID和缓存jclass似乎不一样。那是因为jclass其实是java.lang.Class对象,而方法ID是JNI中定义的一个结构体。如果这里不使用
env—>NewGlobalRef()
函数声明其是一个全局引用的话,在运行的时候可能就会报错:JNI ERROR (app bug): accessed stale local reference 0x5900021
;表明在Jvm中该对象已经被回收了,引用已经失效了。而NewGlobalRef的作用就在于告诉JVM,C++中一直持有该引用,请不要回收。显然这又引发了另外一个问题,你需要在你不需要该引用的时候告诉JVM,那么就需要调用env->DelGlobalRef()
。当然你也可以不调用,那么该Java对象将在你的程序关闭的时候被回收。
测试结果:
<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 18ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 5ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 24ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 44ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 121ms</span> <span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 65ms</span> <span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 259ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
这次的结果表明,如果缓存方法ID和jclass能缩短一半的时间。但仍然不如Java快。这也很好理解,C++创建Java对象最终还是通过Java创建的,反复的通过反射去创建自然不如自身创建来得快。
总结
- JNI中想访问Java Object方法签名、类名和变量名十分重要,一旦确定了就不要轻易单方面修改Java中的定义。因为这会导致JNI找不到相关的方法或类等,而引发JNI错误。
- 虽然JNI提供了各种方法来完成Java的反射操作,但是请酌情使用,因为这会让Java代码与C++代码之间过度依赖。
- 当你需要返回C++中的结构体数据的时候,可以考虑把结构体转换成对应的Java对象返回。