Android JNI(實(shí)現(xiàn)自己的JNI_OnLoad函數(shù))

      網(wǎng)友投稿 1180 2025-03-31

      簡(jiǎn)單的Jni 例子都是映射模式,及對(duì)應(yīng)的Jni 的c/c++ 實(shí)現(xiàn)需要,被java的函數(shù)命名規(guī)則限制死,為了解決這類毛病,引入的JNI_OnLoad這類方法。


      jint JNI_OnLoad(JavaVM* vm, void* reserved)

      該方法在Jni so 被加載時(shí)調(diào)用。該方法告訴VM此C組件使用高級(jí)的JNI版本。如果你的*.so文件沒有使用JNI_OnLoad()函數(shù),VM會(huì)默認(rèn)該*.so是使用最老的JNI1.1版本。新版的JNI做了許多的擴(kuò)充,如果需要使用新版的功能,如JNI 1.4 java.nio.ByteBuffer,就必須藉由JNI_OnLoad()函數(shù)來(lái)告知VM.

      轉(zhuǎn)載自:http://blog.csdn.net/zhenyongyuan123/archive/2010/09/03/5862054.aspx

      實(shí)現(xiàn)JNI中本地函數(shù)注冊(cè)可以兩種方式:

      (1)采用默認(rèn)的本地函數(shù)注冊(cè)流程。

      (2)自己重寫JNI_OnLoad()函數(shù)。(本文介紹)(Android中采用這種)

      Java端代碼:

      package com.jni;

      public class JavaHello {

      public static native String hello();

      static {

      // load library: libtest.so

      try {

      System.loadLibrary("test");

      } catch (UnsatisfiedLinkError ule) {

      System.err.println("WARNING: Could not load library!");

      }

      }

      public staticvoid main(String[] args) {

      String s = new JavaHello().hello();

      System.out.println(s);

      }

      }

      #include

      #include

      #include

      #include

      #include

      JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz)

      {

      printf("hello in c native code.\n");

      return (*env)->NewStringUTF(env, "hello world returned.");

      }

      #define JNIREG_CLASS "com/jni/JavaHello"http://指定要注冊(cè)的類

      /**

      * Table of methods associated with a single class.

      */

      static JNINativeMethod gMethods[] = {

      { "hello", "()Ljava/lang/String;", (void*)native_hello },//綁定

      };

      /*

      * Register several native methods for one class.

      */

      static int registerNativeMethods(JNIEnv* env, constchar* className,

      JNINativeMethod* gMethods, int numMethods)

      {

      jclass clazz;

      clazz = (*env)->FindClass(env, className);

      if (clazz == NULL) {

      return JNI_FALSE;

      }

      if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {

      return JNI_FALSE;

      }

      return JNI_TRUE;

      }

      /*

      * Register native methods for all classes we know about.

      */

      static int registerNatives(JNIEnv* env)

      {

      if (!registerNativeMethods(env, JNIREG_CLASS, gMethods,

      sizeof(gMethods) / sizeof(gMethods[0])))

      return JNI_FALSE;

      return JNI_TRUE;

      }

      /*

      * Set some test stuff up.

      *

      * Returns the JNI version on success, -1 on failure.

      */

      JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)

      {

      JNIEnv* env = NULL;

      jint result = -1;

      if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {

      return -1;

      }

      assert(env != NULL);

      if (!registerNatives(env)) {//注冊(cè)

      return -1;

      }

      /* success -- return valid version number */

      result = JNI_VERSION_1_4;

      return result;

      }

      編譯及運(yùn)行流程:

      Linux環(huán)境下:

      1 設(shè)置三個(gè)環(huán)境變量:

      export JAVA_HOME:=/usr/lib/jvm/java-6-sun-1.6.0.15

      export JAVA_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/com/jfo

      export NATIVE_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/jni

      2 編譯JavaHello.java:

      javac $JAVA_SRC_PATH/JavaHello.java

      3. 編譯NativeHello.c,生成共享庫(kù)

      gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c -o $NATIVE_SRC_PATH/NativeHello.o? $NATIVE_SRC_PATH/NativeHello.c

      gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o $NATIVE_SRC_PATH/libtest.so $NATIVE_SRC_PATH/NativeHello.o

      4. 運(yùn)行

      java com/jni/JavaHello

      Windows環(huán)境下:

      HelloJNI_Load工程

      補(bǔ)充:

      ①JNI_OnUnload()函數(shù)與JNI_OnLoad()相對(duì)應(yīng)的。在加載C組件時(shí)會(huì)立即呼叫JNI_OnLoad()來(lái)進(jìn)行組件內(nèi)的初期動(dòng)作;而當(dāng)VM釋放該C組件時(shí),則會(huì)呼叫JNI_OnUnload()函數(shù)來(lái)進(jìn)行善后清除動(dòng)作。

      ②由于VM通常是多線程(Multi-threading)的執(zhí)行環(huán)境。每一個(gè)線程在呼叫JNI_OnLoad()時(shí),所傳遞進(jìn)來(lái)的JNIEnv指標(biāo)值都是不同的。為了配合這種多線程的環(huán)境,C組件開發(fā)者在撰寫本地函數(shù)時(shí),可藉由JNIEnv指標(biāo)值之不同而避免線程的數(shù)據(jù)沖突問(wèn)題,才能確保所寫的本地函數(shù)能安全地在Android的多線程VM 里安全地執(zhí)行?;谶@個(gè)理由,當(dāng)在呼叫C組件的函數(shù)時(shí),都會(huì)將JNIEnv指標(biāo)值傳遞給它

      Android JNI(實(shí)現(xiàn)自己的JNI_OnLoad函數(shù))

      認(rèn)識(shí)so里的JNI_OnLoad()函數(shù)

      Android JNI 使用的數(shù)據(jù)結(jié)構(gòu)JNINativeMethod詳解

      Android 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:兩列怎么弄(怎么一列變成兩列)
      下一篇:我買的課程還沒看呢‘找不到了(得到以前買的課程沒有了)
      相關(guān)文章
      亚洲人成高清在线播放| 久久精品国产亚洲7777| 亚洲热妇无码AV在线播放| 亚洲国产精品丝袜在线观看| 亚洲成年网站在线观看| 亚洲国产精品xo在线观看| 精品日韩亚洲AV无码一区二区三区 | 亚洲 综合 国产 欧洲 丝袜| 亚洲综合视频在线观看| 在线观看亚洲一区二区| 久久亚洲精品成人无码网站| 亚洲av日韩av激情亚洲| 亚洲伦理一区二区| 久久亚洲精品无码aⅴ大香| 91大神亚洲影视在线| 91久久亚洲国产成人精品性色 | 亚洲精品国产精品乱码不卡√ | 在线aⅴ亚洲中文字幕| 亚洲天堂男人影院| 亚洲综合丁香婷婷六月香| 亚洲人成免费电影| 亚洲人成图片网站| 亚洲欧洲无码AV不卡在线| 亚洲变态另类一区二区三区| 亚洲av日韩综合一区久热| 国产成人亚洲精品无码AV大片| 337P日本欧洲亚洲大胆艺术图| 国产精品亚洲一区二区无码| 亚洲片国产一区一级在线观看| 中文字幕亚洲第一| 亚洲国产精品无码久久一区二区| 亚洲avav天堂av在线不卡 | 亚洲国产小视频精品久久久三级| 亚洲欧洲日产国码高潮αv| 亚洲中文字幕无码不卡电影| 亚洲AV无码专区国产乱码电影| 91亚洲国产在人线播放午夜 | 亚洲18在线天美| 亚洲丶国产丶欧美一区二区三区 | 99久久亚洲综合精品成人网| 亚洲免费视频播放|