博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android NDK开发三:java和C\C++交互
阅读量:6679 次
发布时间:2019-06-25

本文共 5154 字,大约阅读时间需要 17 分钟。

转自:
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 
#include
jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz ){return (*env)->NewStringUTF(env, "Hello from JNI !"); //in creturn 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 applicationusing the JNIEnv interface. *//* Detach the current thread from virtual machine. */(*cachedJvm)->DetachCurrentThread(cachedJvm);

转载于:https://www.cnblogs.com/sesexxoo/p/6189938.html

你可能感兴趣的文章
LeetCode 131. Palindrome Partitioning 20170706
查看>>
我的JavaScript学习笔记
查看>>
Microsoft Client Development MVP 2013 - 2014
查看>>
Jquery blokckUI 快速入门
查看>>
LeetCode 527 Word Abbreviation
查看>>
20160728
查看>>
NOI十连测 第四测 T3
查看>>
Codeforces 414B Mashmokh and ACM
查看>>
阿卡分糖果
查看>>
《软件工程-理论、方法与实践》读书笔记二
查看>>
将字符串str1复制为字符串str2的三种方法
查看>>
Vue项目经验
查看>>
八皇后问题,递归法实现
查看>>
Sharc FLAGS I/O Register(flag0~3)
查看>>
图片等比例缩放
查看>>
Python之异常
查看>>
Stringbuilder & Stringbuffer
查看>>
jackson自动将东八区时间转成标准时间
查看>>
js-浅显基础-正则表达式集
查看>>
Data truncation: Truncated incorrect DOUBLE value错误的解决方案
查看>>