Android JNI 调用 C/C++

来源:互联网 发布:ios 判断数组相同元素 编辑:程序博客网 时间:2024/05/02 11:49

Android JNI 调用 C/C++ 接口

Android 使用 NDK 原生支持调用 c/c++ 接口的代码,只需要在程序中按照 android jni 规范编程就可以直接使用。

C 语言版本

JNI 调用 c 语言相对简单,命名一个 jni 函数,系统会自动注册到 Java 虚拟机,然后 Java 代码里面可以直接调用:

Native 代码:

  1. #include <jni.h>  
  2.   
  3. int add(int x, int y) {  
  4.     return x + y;  
  5. }  
  6. jint  
  7. Java_com_example_android_simplejni_SimpleJNI_add( JNIEnv*  env,  
  8.                                       jobject  this,  
  9.                                       jint     x,  
  10.                                       jint     y )  
  11. {  
  12.     return add(x, y);  

需要注意的是函数名必须是跟 Java 类对应的,比如例子中的包为: package com.example.android.simplejni;  类名为: public class SimpleJNI 

方法名为: add 

然后 Java 类代码里面可以直接加载库,声明为自己的方法:

  1. package com.example.android.simplejni;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class SimpleJNI extends Activity {  
  8.     /** Called when the activity is first created. */  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         TextView tv = new TextView(this);  
  13.         System.loadLibrary("simplejni");  
  14.         int sum = add(23);  
  15.         tv.setText("2 + 3 = " + Integer.toString(sum));  
  16.         setContentView(tv);  
  17.     }  
  18.     public native int add(int  x, int  y);  
  19. }  

C++ 版本

c++ 语言由于跟 Java 一样是面向对象的设计语言,具有更多的特性,只是传递函数就不需要 c++ 了。 那么使用 C++ 代码注册到 Java 虚拟机就相对麻烦一些。

需要手动注册方法: 直接给 代码 吧:development/samples/SimpleJNI/jni/native.cpp

  1. #define LOG_TAG "simplejni native.cpp"  
  2. #include <utils/Log.h>  
  3.   
  4. #include <stdio.h>  
  5.   
  6. #include "jni.h"  
  7.   
  8. static jint  
  9. add(JNIEnv *env, jobject thiz, jint a, jint b) {  
  10. int result = a + b;  
  11.     ALOGI("%d + %d = %d", a, b, result);  
  12.     return result;  
  13. }  
  14.   
  15. static const char *classPathName = "com/example/android/simplejni/Native";  
  16.   
  17. static JNINativeMethod methods[] = {  
  18.   {"add""(II)I", (void*)add },  
  19. };  
  20.   
  21. /* 
  22.  * Register several native methods for one class. 
  23.  */  
  24. static int registerNativeMethods(JNIEnv* env, const char* className,  
  25.     JNINativeMethod* gMethods, int numMethods)  
  26. {  
  27.     jclass clazz;  
  28.   
  29.     clazz = env->FindClass(className);  
  30.     if (clazz == NULL) {  
  31.         ALOGE("Native registration unable to find class '%s'", className);  
  32.         return JNI_FALSE;  
  33.     }  
  34.     if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {  
  35.         ALOGE("RegisterNatives failed for '%s'", className);  
  36.         return JNI_FALSE;  
  37.     }  
  38.   
  39.     return JNI_TRUE;  
  40. }  
  41.   
  42. /* 
  43.  * Register native methods for all classes we know about. 
  44.  * 
  45.  * returns JNI_TRUE on success. 
  46.  */  
  47. static int registerNatives(JNIEnv* env)  
  48. {  
  49.   if (!registerNativeMethods(env, classPathName,  
  50.                  methods, sizeof(methods) / sizeof(methods[0]))) {  
  51.     return JNI_FALSE;  
  52.   }  
  53.   
  54.   return JNI_TRUE;  
  55. }  
  56.   
  57.   
  58. // ----------------------------------------------------------------------------  
  59.   
  60. /* 
  61.  * This is called by the VM when the shared library is first loaded. 
  62.  */  
  63.    
  64. typedef union {  
  65.     JNIEnv* env;  
  66.     void* venv;  
  67. } UnionJNIEnvToVoid;  
  68.   
  69. jint JNI_OnLoad(JavaVM* vm, void* reserved)  
  70. {  
  71.     UnionJNIEnvToVoid uenv;  
  72.     uenv.venv = NULL;  
  73.     jint result = -1;  
  74.     JNIEnv* env = NULL;  
  75.       
  76.     ALOGI("JNI_OnLoad");  
  77.   
  78.     if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {  
  79.         ALOGE("ERROR: GetEnv failed");  
  80.         goto bail;  
  81.     }  
  82.     env = uenv.env;  
  83.   
  84.     if (registerNatives(env) != JNI_TRUE) {  
  85.         ALOGE("ERROR: registerNatives failed");  
  86.         goto bail;  
  87.     }  
  88.       
  89.     result = JNI_VERSION_1_4;  
  90.       
  91. bail:  
  92.     return result;  
  93. }  

Java :SimpleJNI/src/com/example/android/simplejni/SimpleJNI.java

  1. package com.example.android.simplejni;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class SimpleJNI extends Activity {  
  8.     /** Called when the activity is first created. */  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         TextView tv = new TextView(this);  
  13.         int sum = Native.add(23);  
  14.         tv.setText("2 + 3 = " + Integer.toString(sum));  
  15.         setContentView(tv);  
  16.     }  
  17. }  
  18.   
  19. class Native {  
  20.     static {  
  21.         // The runtime will add "lib" on the front and ".o" on the end of  
  22.         // the name supplied to loadLibrary.  
  23.         System.loadLibrary("simplejni");  
  24.     }  
  25.   
  26.     static native int add(int a, int b);  
  27. }  
0 0
原创粉丝点击