概述
本文主要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對象返回。