{"id":411,"date":"2023-02-25T10:57:11","date_gmt":"2023-02-25T02:57:11","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=411"},"modified":"2023-04-29T21:27:54","modified_gmt":"2023-04-29T13:27:54","slug":"android-ndk-basic-jni-data-type-c-calls-java","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/02\/25\/android-ndk-basic-jni-data-type-c-calls-java\/","title":{"rendered":"Android NDK\u57fa\u784011\uff1aJNI\u6570\u636e\u7c7b\u578b_C\u8c03\u7528Java"},"content":{"rendered":"<h2>JNI\u6570\u636e\u7c7b\u578b<\/h2>\n<h3>jclass\u548cjobject<\/h3>\n<pre><code>\/\/\u6bcf\u4e2anative\u51fd\u6570\uff0c\u90fd\u81f3\u5c11\u6709\u4e24\u4e2a\u53c2\u6570\uff08JNIEnv*, jclass\u6216\u8005jobject)\n\/\/1\uff09\u5f53native\u65b9\u6cd5\u4e3a\u9759\u6001\u65b9\u6cd5\u65f6\uff1a\n\/\/jclass \u4ee3\u8868native\u65b9\u6cd5\u6240\u5c5e\u7c7b\u7684class\u5bf9\u8c61(JniTest.class)\n\/\/2\uff09\u5f53native\u65b9\u6cd5\u4e3a\u975e\u9759\u6001\u65b9\u6cd5\u65f6\uff1a\n\/\/jobject \u4ee3\u8868native\u65b9\u6cd5\u6240\u5c5e\u7684\u5bf9\u8c61<\/code><\/pre>\n<p><!-- more --><\/p>\n<h3>\u57fa\u672c\u6570\u636e\u7c7b\u578b<\/h3>\n<p>Java\u57fa\u672c\u6570\u636e\u7c7b\u578b\u4e0eJNI\u6570\u636e\u7c7b\u578b\u7684\u6620\u5c04\u5173\u7cfb<\/p>\n<table>\n<thead>\n<tr>\n<th>Java Type<\/th>\n<th>Native Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>boolean<\/td>\n<td>jboolean<\/td>\n<td>unsigned 8 bits<\/td>\n<\/tr>\n<tr>\n<td>byte<\/td>\n<td>jbyte<\/td>\n<td>signed 8 bits<\/td>\n<\/tr>\n<tr>\n<td>char<\/td>\n<td>jchar<\/td>\n<td>unsigned 16 bits<\/td>\n<\/tr>\n<tr>\n<td>short<\/td>\n<td>jshort<\/td>\n<td>signed 16 bits<\/td>\n<\/tr>\n<tr>\n<td>int<\/td>\n<td>jint<\/td>\n<td>signed 32 bits<\/td>\n<\/tr>\n<tr>\n<td>long<\/td>\n<td>jlong<\/td>\n<td>signed 64 bits<\/td>\n<\/tr>\n<tr>\n<td>float<\/td>\n<td>jfloat<\/td>\n<td>32 bits<\/td>\n<\/tr>\n<tr>\n<td>double<\/td>\n<td>jdouble<\/td>\n<td>64 bits<\/td>\n<\/tr>\n<tr>\n<td>void<\/td>\n<td>void<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\u5f15\u7528\u7c7b\u578b(\u5bf9\u8c61)<\/h3>\n<pre><code class=\"language-c\">\/\/String jstring\n\/\/Object jobject\n\/\/Class jobject\n\/\/\u6570\u7ec4\uff0c\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u6570\u7ec4\n\/\/boolean[] jbooleanArray\n\/\/byte[] jbyteArray\n\/\/char[] jcharArray\n\/\/short[] jshortArray\n\/\/int[] jintArray\n\/\/long[] jlongArray\n\/\/float[] jfloatArray\n\/\/double[] jdoubleArray\n\/\/\u5bf9\u8c61\u6570\u7ec4\n\/\/String[] jobjectArray\n\/\/object[] jobjectArray<\/code><\/pre>\n<h2>C\/C++\u8bbf\u95eeJava\u7684\u6210\u5458<\/h2>\n<p>\u7c7b\u578b\u7b7e\u540d<\/p>\n<table>\n<thead>\n<tr>\n<th>Type Signature<\/th>\n<th>Java Type<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Z<\/td>\n<td>boolean<\/td>\n<\/tr>\n<tr>\n<td>B<\/td>\n<td>byte<\/td>\n<\/tr>\n<tr>\n<td>C<\/td>\n<td>char<\/td>\n<\/tr>\n<tr>\n<td>S<\/td>\n<td>short<\/td>\n<\/tr>\n<tr>\n<td>I<\/td>\n<td>int<\/td>\n<\/tr>\n<tr>\n<td>J<\/td>\n<td>long<\/td>\n<\/tr>\n<tr>\n<td>F<\/td>\n<td>float<\/td>\n<\/tr>\n<tr>\n<td>D<\/td>\n<td>double<\/td>\n<\/tr>\n<tr>\n<td>Ljava\/lang\/String<\/td>\n<td>String<\/td>\n<\/tr>\n<tr>\n<td>L{fully-qualified-class};<\/td>\n<td>fully-qualified-class<\/td>\n<\/tr>\n<tr>\n<td>[{type}<\/td>\n<td>type[]<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\u8bbf\u95ee\u5c5e\u6027<\/h3>\n<pre><code class=\"language-c\">#define _CRT_SECURE_NO_WARNINGS\n#include &quot;cn_appblog_jni_JniTest.h&quot;\n#include &lt;string.h&gt;\n\n\/\/\u4fee\u6539\u5c5e\u6027key\nJNIEXPORT jstring JNICALL Java_cn_appblog_jni_JniTest_accessField\n  (JNIEnv *env, jobject jobj) {\n    \/\/jobj\u662ft\u5bf9\u8c61\uff0cJniTest.class\n    jclass cls = (*env)-&gt;GetObjectClass(env, jobj);\n    \/\/jfieldID\n    \/\/\u5c5e\u6027\u540d\u79f0\uff0c\u5c5e\u6027\u7b7e\u540d\n    jfieldID fid = (*env)-&gt;GetFieldID(env, cls, &quot;key&quot;, &quot;Ljava\/lang\/String;&quot;);    \n\n    \/\/jason &gt;&gt; super jason\n    \/\/\u83b7\u53d6key\u5c5e\u6027\u7684\u503c\n    \/\/Get&lt;Type&gt;Field\n    jstring jstr = (*env)-&gt;GetObjectField(env, jobj, fid);    \n    printf(&quot;jstr:%#x\\n&quot;, &amp;jstr);\n\n    \/\/jstring -&gt; c\u5b57\u7b26\u4e32\n    \/\/\u7b2c\u4e09\u4e2a\u53c2\u6570isCopy \u662f\u5426\u590d\u5236\uff08true\u4ee3\u8868\u590d\u5236\uff0cfalse\u4e0d\u590d\u5236\uff09\n    char *c_str = (*env)-&gt;GetStringUTFChars(env, jstr, JNI_FALSE);\n    \/\/\u62fc\u63a5\u5f97\u5230\u65b0\u7684\u5b57\u7b26\u4e32\n    char text[20] = &quot;super &quot;;\n    strcat(text, c_str);\n\n    \/\/c\u5b57\u7b26\u4e32 -&gt;jstring\n    jstring new_jstr = (*env)-&gt;NewStringUTF(env, text);\n\n    \/\/\u4fee\u6539key\n    \/\/Set&lt;Type&gt;Field\n    (*env)-&gt;SetObjectField(env, jobj, fid, new_jstr);\n\n    printf(&quot;new_jstr:%#x\\n&quot;, &amp;new_jstr);\n\n    return new_jstr;\n}<\/code><\/pre>\n<h3>\u8bbf\u95ee\u9759\u6001\u5c5e\u6027<\/h3>\n<pre><code class=\"language-c\">JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_accessStaticField\n  (JNIEnv *env, jobject jobj) {\n    \/\/jclass\n    jclass cls = (*env)-&gt;GetObjectClass(env, jobj);\n    \/\/jfieldID\n    jfieldID fid = (*env)-&gt;GetStaticFieldID(env, cls, &quot;count&quot;, &quot;I&quot;);\n    \/\/GetStatic&lt;Type&gt;Field\n    jint count = (*env)-&gt;GetStaticIntField(env, cls, fid);\n    count++;\n    \/\/\u4fee\u6539\n    \/\/SetStatic&lt;Type&gt;Field\n    (*env)-&gt;SetStaticIntField(env, cls, fid, count);\n}<\/code><\/pre>\n<h3>\u8bbf\u95ee\u5bf9\u8c61\u65b9\u6cd5<\/h3>\n<pre><code class=\"language-c\">\/\/\u83b7\u53d6\u6307\u5b9a\u7c7b\u6240\u6709\u5c5e\u6027\u548c\u65b9\u6cd5\u7684\u7b7e\u540d\n> javap -s -p cn.appblog.jni.JniTest<\/code><\/pre>\n<pre><code class=\"language-c\">JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_accessMethod\n  (JNIEnv *env, jobject jobj) {\n    \/\/jclass\n    jclass cls = (*env)-&gt;GetObjectClass(env, jobj);\n    \/\/jmethodID\n    jmethodID mid = (*env)-&gt;GetMethodID(env, cls, &quot;genRandomInt&quot;, &quot;(I)I&quot;);\n    \/\/\u8c03\u7528\n    \/\/Call&lt;Type&gt;Method\n    jint random = (*env)-&gt;CallIntMethod(env, jobj, mid, 200);\n    printf(&quot;random num:%ld&quot;, random);\n\n    \/\/.....\n}<\/code><\/pre>\n<h3>\u8bbf\u95ee\u9759\u6001\u65b9\u6cd5<\/h3>\n<pre><code class=\"language-c\">JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_accessStaticMethod\n  (JNIEnv *env, jobject jobj) {\n    \/\/jclass\n    jclass cls = (*env)-&gt;GetObjectClass(env, jobj);\n    \/\/jmethodID    \n    jmethodID mid = (*env)-&gt;GetStaticMethodID(env, cls, &quot;getUUID&quot;, &quot;()Ljava\/lang\/String;&quot;);\n\n    \/\/\u8c03\u7528\n    \/\/CallStatic&lt;Type&gt;Method\n    jstring uuid = (*env)-&gt;CallStaticObjectMethod(env, cls, mid);\n\n    \/\/\u968f\u673a\u6587\u4ef6\u540d\u79f0 uuid.txt\n    \/\/jstring -&gt; char*\n    \/\/isCopy JNI_FALSE\uff0c\u4ee3\u8868java\u548cc\u64cd\u4f5c\u7684\u662f\u540c\u4e00\u4e2a\u5b57\u7b26\u4e32\n    char *uuid_str = (*env)-&gt;GetStringUTFChars(env, uuid, JNI_FALSE);\n    \/\/\u62fc\u63a5\n    char filename[100];\n    sprintf(filename, &quot;D:\/\/%s.txt&quot;, uuid_str);\n    FILE *fp = fopen(filename,&quot;w&quot;);\n    fputs(&quot;I love Joe&quot;, fp);\n    close(fp);\n}<\/code><\/pre>\n<h3>\u8bbf\u95ee\u6784\u9020\u65b9\u6cd5<\/h3>\n<pre><code class=\"language-c\">\/\/\u4f7f\u7528java.util.Date\u4ea7\u751f\u4e00\u4e2a\u5f53\u524d\u7684\u65f6\u95f4\u6233\nJNIEXPORT jobject JNICALL Java_cn_appblog_jni_JniTest_accessConstructor\n  (JNIEnv *env, jobject jobj) {\n    jclass cls = (*env)-&gt;FindClass(env, &quot;java\/util\/Date&quot;);\n    \/\/jmethodID\n    jmethodID constructor_mid = (*env)-&gt;GetMethodID(env, cls, &quot;&lt;init&gt;&quot;, &quot;()V&quot;);\n    \/\/\u5b9e\u4f8b\u5316\u4e00\u4e2aDate\u5bf9\u8c61\n    jobject date_obj = (*env)-&gt;NewObject(env, cls, constructor_mid);\n    \/\/\u8c03\u7528getTime\u65b9\u6cd5\n    jmethodID mid = (*env)-&gt;GetMethodID(env, cls, &quot;getTime&quot;, &quot;()J&quot;);\n    jlong time = (*env)-&gt;CallLongMethod(env, date_obj, mid);\n\n    printf(&quot;\\ntime:%lld\\n&quot;, time);\n\n    return date_obj;\n}<\/code><\/pre>\n<h3>Java\u5c42\u8c03\u7528<\/h3>\n<pre><code class=\"language-c\">public class JniTest {\n\n    public String key = &quot;joe&quot;;\n\n    public static int count = 9;\n\n    \/\/\u8bbf\u95ee\u5c5e\u6027\uff0c\u8fd4\u56de\u4fee\u6539\u4e4b\u540e\u7684\u5c5e\u6027\u5185\u5bb9\n    public native String accessField();\n\n    public native void accessStaticField();\n\n    public native void accessMethod();\n\n    public native void accessStaticMethod();\n\n    public native Date assessConstructor();\n\n    public static void main(String[] args) {\n        JniTest t = new JniTest();\n\n        System.out.println(&quot;key\u4fee\u6539\u524d\uff1a&quot; + t.key);\n        t.accessField();\n        System.out.println(&quot;key\u4fee\u6539\u540e\uff1a&quot; + t.key);\n\n        System.out.println(&quot;count\u4fee\u6539\u524d\uff1a&quot; + count);\n        t.accessStaticField();\n        System.out.println(&quot;count\u4fee\u6539\u540e\uff1a&quot; + count);\n\n        t.accessMethod();\n        t.accessStaticMethod();\n        t.assessConstructor();\n    }\n\n    \/\/\u4ea7\u751f\u6307\u5b9a\u8303\u56f4\u7684\u968f\u673a\u6570\n    public int genRandomInt(int max) {\n        System.out.println(&quot;genRandomInt \u6267\u884c\u4e86...&quot;);\n        return new Random().nextInt(max); \n    }\n\n    \/\/\u4ea7\u751fUUID\u5b57\u7b26\u4e32\n    public static String getUUID() {\n        return UUID.randomUUID().toString();\n    }\n\n    \/\/\u52a0\u8f7d\u52a8\u6001\u5e93\n    static {    \n        System.loadLibrary(&quot;JniTest&quot;);\n    }\n\n}<\/code><\/pre>\n<h3>\u8c03\u7528\u7236\u7c7b\u7684\u65b9\u6cd5<\/h3>\n<pre><code class=\"language-c\">public class Human {\n\n    @Override\n    public void sayHi() {\n        System.out.println(&quot;\u7236\u7c7b\uff1asayHi&quot;);\n    }\n\n}\n\npublic class Man extends Human {\n\n    @Override\n    public void sayHi() {\n        super.sayHi();\n        System.out.println(&quot;\u5b50\u7c7b\uff1asayHi&quot;);\n    }\n\n}\n\npublic class JniTest {\n\n    public Human human = new Man();\n\n    public native Date assessNonvirtualMethod();\n\n    public static void main(String[] args) {\n        JniTest t = new JniTest();\n        t.assessNonvirtualMethod();\n    }\n\n    \/\/\u52a0\u8f7d\u52a8\u6001\u5e93\n    static {    \n        System.loadLibrary(&quot;JniTest&quot;);\n    }\n\n}<\/code><\/pre>\n<pre><code class=\"language-c\">JNIEXPORT void JNICALL Java_cn_appblog_jni_JniTest_accessNonvirtualMethod\n  (JNIEnv *env, jobject jobj) {\n    jclass cls = (*env)-&gt;GetObjectClass(env, jobj);\n    \/\/\u83b7\u53d6man\u5c5e\u6027\uff08\u5bf9\u8c61\uff09\n    jfieldID fid = (*env)-&gt;GetFieldID(env, cls, &quot;human&quot;, &quot;Lcc\/androidios\/jni\/Human;&quot;);\n    \/\/\u83b7\u53d6\n    jobject human_obj = (*env)-&gt;GetObjectField(env, jobj, fid);\n\n    \/\/\u6267\u884csayHi\u65b9\u6cd5\n    jclass human_cls = (*env)-&gt;FindClass(env, &quot;cc\/androidios\/jni\/Human&quot;); \/\/\u6ce8\u610f\uff1a\u4f20\u7236\u7c7b\u7684\u540d\u79f0\n    jmethodID mid = (*env)-&gt;GetMethodID(env, human_cls, &quot;sayHi&quot;, &quot;()V&quot;);\n\n    \/\/\u6267\u884c\n    \/\/(*env)-&gt;CallObjectMethod(env, human_obj, mid);\n    \/\/\u8c03\u7528\u7684\u7236\u7c7b\u7684\u65b9\u6cd5\n    (*env)-&gt;CallNonvirtualObjectMethod(env, human_obj, human_cls, mid);\n}<\/code><\/pre>\n<h3>\u4e2d\u6587\u95ee\u9898<\/h3>\n<pre><code class=\"language-c\">public class JniTest {\n\n    public native String chineseChars(String content);\n\n    public static void main(String[] args) {\n        JniTest t = new JniTest();\n        t.chineseChars(&quot;\u4e2d\u6587&quot;);\n    }\n\n    \/\/\u52a0\u8f7d\u52a8\u6001\u5e93\n    static {    \n        System.loadLibrary(&quot;JniTest&quot;);\n    }\n\n}\n\nJNIEXPORT jstring JNICALL Java_cn_appblog_jni_JniTest_chineseChars\n  (JNIEnv *env, jobject jobj, jstring content) {\n    \/\/\u8f93\u51fa\n    \/\/char *c_str = (*env)-&gt;GetStringUTFChars(env, content, JNI_FALSE);\n    \/\/printf(&quot;%s\\n&quot;, c_str);\n\n    \/\/c -&gt; jstring\n    char *c_str = &quot;\u9a6c\u84c9\u4e0e\u5b8b\u6c5f&quot;;\n    \/\/char c_str[] = &quot;\u9a6c\u84c9\u4e0e\u5b8b\u5586&quot;;\n    \/\/jstring jstr = (*env)-&gt;NewStringUTF(env, c_str);\n    \/\/\u6267\u884cString(byte bytes[], String charsetName)\u6784\u9020\u65b9\u6cd5\u9700\u8981\u7684\u6761\u4ef6\n    \/\/1.jmethodID\n    \/\/2.byte\u6570\u7ec4\n    \/\/3.\u5b57\u7b26\u7f16\u7801jstring\n\n    jclass str_cls = (*env)-&gt;FindClass(env, &quot;java\/lang\/String&quot;);\n    jmethodID constructor_mid = (*env)-&gt;GetMethodID(env, str_cls, &quot;&lt;init&gt;&quot;, &quot;([BLjava\/lang\/String;)V&quot;);\n\n    \/\/jbyte -&gt; char \n    \/\/jbyteArray -&gt; char[]\n    jbyteArray bytes = (*env)-&gt;NewByteArray(env, strlen(c_str));\n    \/\/byte\u6570\u7ec4\u8d4b\u503c\n    \/\/0-&gt;strlen(c_str)\uff0c\u4ece\u5934\u5230\u5c3e\n    \/\/\u5bf9\u7b49\u4e8e\uff0c\u4ecec_str\u8fd9\u4e2a\u5b57\u7b26\u6570\u7ec4\uff0c\u590d\u5236\u5230bytes\u8fd9\u4e2a\u5b57\u7b26\u6570\u7ec4\n    (*env)-&gt;SetByteArrayRegion(env, bytes, 0, strlen(c_str), c_str);\n\n    \/\/\u5b57\u7b26\u7f16\u7801jstring\n    jstring charsetName = (*env)-&gt;NewStringUTF(env, &quot;GB2312&quot;);\n\n    \/\/\u8c03\u7528\u6784\u9020\u51fd\u6570\uff0c\u8fd4\u56de\u7f16\u7801\u4e4b\u540e\u7684jstring\n    return (*env)-&gt;NewObject(env, str_cls, constructor_mid, bytes, charsetName);\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>JNI\u6570\u636e\u7c7b\u578b jclass\u548cjobject \/\/\u6bcf\u4e2anative\u51fd\u6570\uff0c\u90fd\u81f3\u5c11\u6709\u4e24\u4e2a\u53c2\u6570\uff08JNIEnv*, j [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[133],"class_list":["post-411","post","type-post","status-publish","format-standard","hentry","category-android-ndk","tag-jni"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=411"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/411\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}