zoukankan      html  css  js  c++  java
  • Android NDK开发三:java和C\C++交互


    1、定义native方法并加载动态链接库:

    public class HelloJni extends Activity
    {
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
    
            TextView  tv = new TextView(this);
            tv.setText( stringFromJNI() );
            setContentView(tv);
        }
    
    
        public native String  stringFromJNI();
    
    
        public native String  unimplementedStringFromJNI();
    
    
        static {
            System.loadLibrary("hello-jni");
        }
    }

    2、实现native方法:

    #include <string.h>
    #include <jni.h>
    jstring
    Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
    jobject thiz )
    {
    return (*env)->NewStringUTF(env, "Hello from JNI !"); //in c
    return
    env->NewStringUTF("Hello from JNI !"); //in c++
    
    }

    若要定义静态方法:

    JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI
    (JNIEnv * env, jclass clazz);

    头文件可以用javah工具生成:

    进入命令行,切换到项目的bin目录下的classes下面,执行 javah -classpath . -jni .类名。

    或者:cd src目录中,执行 javah .类名

     

    3、数据

    原始数据类型:

    引用数据类型:

     

    4、字符窜的操作:
    1)新建字符串:

    jstring javaString;

    javaString = (*env)->NewStringUTF(env, "Hello World!");

    2)把java string转换成c string

    const jbyte* str;
    jboolean isCopy;
    str = (*env)->GetStringUTFChars(env, javaString, &isCopy);
    if (0 != str) {
    printf("Java string: %s", str);
    if (JNI_TRUE == isCopy) {
    printf("C string is a copy of the Java string.");
    } else {
    printf("C string points to actual string.");
    }
    (*env)->ReleaseStringUTFChars(env, javaString, str);

    5、数组的操作:

    1)新建java数组:

    jintArray javaArray;
    javaArray = (*env)->NewIntArray(env, 10);
    if (0 != javaArray) {
    /* You can now use the array. */
    }

    2)获取数组的值:

    jint nativeArray[10];
    //将java array 复制到 c array (
    *env)->GetIntArrayRegion(env, javaArray, 0, 10, nativeArray);
    //将 c array 还原城 java array
    (*env)->SetIntArrayRegion(env, javaArray, 0, 10, nativeArray);

    获取数组指针:

    jint* nativeDirectArray;
    jboolean isCopy;
    nativeDirectArray = (*env)->GetIntArrayElements(env, javaArray, &isCopy);
    //...
    (*env)->ReleaseIntArrayElements(env, javaArray, nativeDirectArray, 0);

    6、C\C++获取java成员变量

    public class JavaClass {
    /** Instance field */
    private String instanceField = "Instance Field";
    /** Static field */
    private static String staticField = "Static Field";
    ...
    }

    1)获取Field ID

    jclass clazz;
    clazz = (*env)->GetObjectClass(env, instance);
    jfieldID instanceFieldId;
    instanceFieldId = (*env)->GetFieldID(env, clazz,
    "instanceField", "Ljava/lang/String;");
    jfieldID staticFieldId;
    staticFieldId = (*env)->GetStaticFieldID(env, clazz,
    "staticField", "Ljava/lang/String;");

    2)获取Static Field

    jstring staticField;
    staticField = (*env)->GetStaticObjectField(env, clazz, staticFieldId);

    7、C\C++调用java函数

    public class JavaClass {
    /**
    * Instance method.
    */
    private String instanceMethod() {
    return "Instance Method";
    }
    /**
    * Static method.
    */
    private static String staticMethod() {
    return "Static Method";
    }
    ...
    }

    1)获取Method ID:

    成员函数:

    jmethodID instanceMethodId;
    instanceMethodId = (*env)->GetMethodID(env, clazz,
    "instanceMethod", "()Ljava/lang/String;");

    静态函数:

    jmethodID staticMethodId;
    staticMethodId = (*env)->GetStaticMethodID(env, clazz,
    "staticMethod", "()Ljava/lang/String;");

    2)调用:

    jstring instanceMethodResult;
    instanceMethodResult = (*env)->CallStringMethod(env,
    instance, instanceMethodId);

    变量和函数的描述符:

    javap工具可以提取从编译过的class files 中提取这些描述符:

    javap –classpath bin/classes –p –s com.example.hellojni.HelloJni

     

    8、处理异常:

    public class JavaClass {
    /**
    * Throwing method.
    */
    private void throwingMethod() throws NullPointerException {
       throw new NullPointerException("Null pointer");
    }
    /**
    * Access methods native method.
    */
    private native void accessMethods();
    }
    jthrowable ex;
    ...
    (*env)->CallVoidMethod(env, instance, throwingMethodId);
    ex = (*env)->ExceptionOccurred(env);
    if (0 != ex) {
    (*env)->ExceptionClear(env);
    /* Exception handler. */
    }

    从c\c++抛异常:

    jclass clazz;
    ...
    clazz = (*env)->FindClass(env, "java/lang/NullPointerException");
    if (0 ! = clazz) {
    (*env)->ThrowNew(env, clazz, "Exception message.");
    }

    9、本地和全局变量:

    1)本地变量在函数结束时自动释放内存:

    jclass clazz;
    clazz = (*env)->FindClass(env, "java/lang/String");

    2)新建全局变量:

    jclass localClazz;
    jclass globalClazz;
    ...
    localClazz = (*env)->FindClass(env, "java/lang/String");
    globalClazz = (*env)->NewGlobalRef(env, localClazz);
    ...
    (*env)->DeleteLocalRef(env, localClazz);

    3)释放全局变量:

    (*env)->DeleteGlobalRef(env, globalClazz);

    4)弱全局引用:
    弱全局引用可以被内存自动回收:

    jclass weakGlobalClazz;
    weakGlobalClazz = (*env)->NewWeakGlobalRef(env, localClazz);
    if (JNI_FALSE == (*env)->IsSameObject(env, weakGlobalClazz, NULL)) {
    /* Object is still live and can be used. */
    } else {
    /* Object is garbage collected and cannot be used. */
    }
    (*env)->DeleteWeakGlobalRef(env, weakGlobalClazz);

    10、线程:

    synchronized(obj) {
    /* Synchronized thread-safe code block. */
    }
    if (JNI_OK == (*env)->MonitorEnter(env, obj)) {
    /* Error handling. */
    }
    /* Synchronized thread-safe code block. */
    if (JNI_OK == (*env)->MonitorExit(env, obj)) {
    /* Error handling. */
    }

    native线程不能和java直接通信,必须先绑定到javaVM

    JavaVM* cachedJvm;
    ...
    JNIEnv* env;
    ...
    /* Attach the current thread to virtual machine. */
    (*cachedJvm)->AttachCurrentThread(cachedJvm, &env, NULL);
    /* Thread can communicate with the Java application
    using the JNIEnv interface. */
    /* Detach the current thread from virtual machine. */
    (*cachedJvm)->DetachCurrentThread(cachedJvm);
  • 相关阅读:
    NTC温度采集之数据拟合——freemat软件实现
    头文件中不能定义变量
    好的博客空间收藏
    STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本) 的工程文件目录
    STM32F407VET6之IAR之ewarm7.80.4工程建立(基于官方固件库1.6版本)
    JAVA反射机制o
    Java反射机制
    c+内存管理机制
    java内存空间详解
    JAVA内存管理再解
  • 原文地址:https://www.cnblogs.com/shangdahao/p/3053971.html
Copyright © 2011-2022 走看看