Android JNI C/C++调用Java方法
2018-02-05 22:43
621 查看
JNI环境的支持
Android JNI编程从Java方法来调用native方法是比较容易的, 因为Java本身就提供了native关键字作为索引,只要正确的对应Java方法和native方法的包名,做到这一步并不难. 而从C/C++方法调用Java方法则稍复杂一点,因为C/C++没有提供跨语言调用的直接支持,所以需要由Java的JNI运行环境来提供帮助. 每一个JNI native方法的声明一般是这样的: extern "C" JNIEXPORT jstring JNICALL Java_com_sliver_cx_android_1test_MainActivity_stringFromJNI(JNIEnv *env,jobject); 一个个关键字的作用是: 1. extern "C" C/C++的声明关键字 表明这个jni方法是按照C的语法进行编译的. 2. JNIEXPORT 在jni的固件代码中这样声明 #define JNIEXPORT __attribute__ ((visibility ("default"))) visibility ("default")意味着GCC在生成动态库的时候 默认这个方法的符号是被隐藏的 这样做应该是为了除了这个apk外不让其他程序使用这个库的这个方法 3. Java_com_sliver_cx_android_1test_MainActivity_stringFromJNI jni方法名:命名格式 包名_方法名 anroid_1test这个数字1似乎是ide自己加上的 实际上在调用FindClass寻找class时,不应该带有这个1. 4. JNIEnv *env,jobject JNI方法的默认参数 env是JNI的运行环境 jobject是调用这个native方法的Java类
Java签名
Java方法是带有签名的,而C/C++ native方法要调用Java方法 需要知道Java方法的签名. 在terminal下: 首先编译出class文件 javac test.java 执行 javap -s test可以输出类test中方法的签名 签名对应规则 void call(); 对应 ()V 括号内是参数签名 括号后是返回值签名 V对应void 引申出的多个参数签名 void call(int a); 对应 (I)V int call(int a, char b);对应 (IC)I
JNI api
1. FindClass() 函数原型 jclass FindClass(const char* name) { return functions->FindClass(this, name); } FindClass用来寻找在JNI环境中的Java Class name为指定的包名 例如 FindClass("com/cx/test/Test"); // com/cx/test是包名 Test是类名 2. GetMethod 函数原型 jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) { return functions->GetMethodID(this, clazz, name, sig); } GetMethod用来寻找JNI环境中的java类的方法 clazz为调用这个native方法的Java类 name为寻找的Java方法名 sig为Java方法的签名 例如 GetMethod(obj, "call", "()V");
应用举例
Java class: public class Test { public void call(int nb) { System.out.println("cnt" + nb); } public native test_call(); } 调用 Java Class: public class Call { public static void main(String[] args) { Test a = new Test(); a.test_call(); } } JNI cpp: extern "C" JNIEXPORT void JNICALL Java_com_cx_test_Test_call( JNIEnv *env, jobject obj, int cnt) { jclass myclass = env->FindClass("com/cx/test/Test"); if (myclass == nullptr) { LOGI("failed to find class"); return; } jmethodID myid = env->GetMethodID(myclass, "call", "(I)V"); if (myid == nullptr) { LOGI("failed to get method id"); return; } env->CallVoidMethod(obj, myid, 5); }
相关文章推荐
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android JNI 通过C/C++调用JAVA方法
- Android-NDK开发之基础--Android JNI实例代码(一)-- 在JNI中执行Java方法--C/C++调用Java
- Android 在JNI中执行Java方法--C/C++调用Java
- 在eclipse下,JAVA通过JNI调用C++方法的简单例子(非android)
- Android JNI-c/c++调用java方法
- Android中简单的JNI使用,C++调用JAVA
- AndroidJNI 通过C++调用JAVA
- android中关于jni调用java层方法的一些误导和见解
- Android JNI通过C++调用JAVA
- android-JNI学习之java和c++相互调用
- Android JNI通过C++调用JAVA
- AndroidJNI 通过C++调用JAVA
- Android 中Java 和C/C++的相互调用方法
- 在Android中,通过JNI实现C++与Java相互调用
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- Android JNI 使用的数据结构JNINativeMethod详解 ||建立Android SDK下的JNI、JAVA应用完整步骤---Android JAVA调用C++代码
- Android 中Java 和C/C++的相互调用方法
- AndroidJNI 通过C++调用JAVA