赞
踩
JNI即 java native interface,是jdk里边的一部分属于java内容,主要确保java 与 native层(C/C++)通信。C/C++一般用于高效率的数学运算、游戏的实时渲染、音视频编码解码等。
此时需要通过jni进行转换。
例如:java层中的变量 String name = "王六";
Jni层 jstring name = "王六";
c/c++层 char * name = "王六";
Jni的调用类似java的反射调用。
C/C++调用java类对象的属性/方法 的 签名规则
常用规则如下:
java类型----------属性类型符号
boolean----------Z
byte----------B
char----------C
short----------S
int----------I
long----------J
float----------F
double----------D
void----------V
object----------L完整的类名;
method(参数类型)返回值类型 ---------- "java": void name(int a,double b) "c++": (ID)V 其中(ID)表示入参的两个类型
可通过javap获取class文件的对应签名类型
1、创建C++ 工程
2、导入C/C++文件
3、java/kotlin加载C/C++代码
native.cpp
- #include <jni.h>
- #include <string>
-
- //extern "C" :下边的代码采用C的编译方式
- //JNIEXPORT:JNI重要标记关键字,不能少(VS编译能通过,运行会报错) / (AS 运行不会报错), 规则(标记为该方法可以被外部调用) Windows内部规则,与Linux内部规则 不同
- //jstring:代表 java 中的 String
- //JNICALL : 也是一个关键字,(可以少的) jni call (约束函数入栈顺序,和堆栈内存清理的规则)
- //jobject: java传递下来的对象,就是本项目中 MainActivity 对象
-
- extern "C" JNIEXPORT jstring JNICALL
- // 规则:
- //Java_包名(以_连接,如果原包名中有下划线则表示1)_类名_方法名
- Java_com_wangyb_c_1xiangxue_1project_MainActivity_stringFromJNI(
- JNIEnv* env,
- jobject /* this */) {
- std::string hello = "Hello from C++";
- // 如果是c文件 native-lib.c
- //JNIEnv* env 是二级指针,使用时需要通过(*env)-> 调用
- return env->NewStringUTF(hello.c_str());
- }
-
-
- //jclass :java传递下来的 class 对象,就是本项目中的 MainActivity class
- extern "C" JNIEXPORT void JNICALL
- Java_com_wangyb_c_1xiangxue_1project_MainActivity_changeName(JNIEnv* env,jobject obj) {
- // 如果是c++文件 native-lib.cpp
- //JNIEnv* env 是一级指针,使用时可直接调用env->,调用原理如下
- // 1.修改name
- jclass mainActivityCls = env->GetObjectClass(obj);
- jfieldID name_fid = env->GetFieldID(mainActivityCls, "name","Ljava/lang/String;");
- jstring value = env->NewStringUTF("李老八");
- env->SetObjectField(obj, name_fid, value);
- //如果在c中,c是没有对象的,想持有env环境必须传入进去
- jstring value = (*env)->NewStringUTF(env,"李老八");
- }
c文件
native.c
- #include <jni.h>
- //#include <string>
-
- //extern "C" :下边的代码采用C的编译方式
- //JNIEXPORT:JNI重要标记关键字,不能少(VS编译能通过,运行会报错) / (AS 运行不会报错), 规则(标记为该方法可以被外部调用) Windows内部规则,与Linux内部规则 不同
- //jstring:代表 java 中的 String
- //JNICALL : 也是一个关键字,(可以少的) jni call (约束函数入栈顺序,和堆栈内存清理的规则)
- //jobject: java传递下来的对象,就是本项目中 MainActivity 对象
-
- //extern "C"
- JNIEXPORT jstring JNICALL
- // 规则:
- //Java_包名(以_连接,如果原包名中有下划线则表示1)_类名_方法名
- Java_com_wangyb_c_1xiangxue_1project_MainActivity_stringFromJNI(
- JNIEnv* env,
- jobject obj) {
- // std::string hello = "Hello from C++";
- // 如果是c文件 native-lib.c
- //JNIEnv* env 是二级指针,使用时需要通过(*env)-> 调用
- return (*env)->NewStringUTF(env,"Hello from C++");
- }
-
-
- //jclass :java传递下来的 class 对象,就是本项目中的 MainActivity class
- //extern "C"
- JNIEXPORT void JNICALL
- Java_com_wangyb_c_1xiangxue_1project_MainActivity_changeName(JNIEnv* env,jobject obj) {
- // 如果是c++文件 native-lib.cpp
- //JNIEnv* env 是一级指针,使用时可直接调用env->
- // 1.修改name
- jclass mainActivityCls = (*env)->GetObjectClass(env,obj);
- jfieldID name_fid = (*env)->GetFieldID(env,mainActivityCls, "name","Ljava/lang/String;");
- jstring value = (*env)->NewStringUTF(env,"李老八");
- (*env)->SetObjectField(env,obj, name_fid, value);
- }
jni.h文件中
-
- struct _JNIEnv;
- struct _JavaVM;
- typedef const struct JNINativeInterface* C_JNIEnv;
-
- //此处表示是c++
- #if defined(__cplusplus)
- //JNIEnv是别名,所以JNIEnv* env是一级指针
- typedef _JNIEnv JNIEnv;
- typedef _JavaVM JavaVM;
- #else
- //此处表示c 。JNINativeInterface* JNIEnv是一个一级指针。所以JNIEnv* env是二级指针(形参 *xxx 已经是一个二级指针了),调用时需要(*env)
- typedef const struct JNINativeInterface* JNIEnv;
- typedef const struct JNIInvokeInterface* JavaVM;
- #endif
-
-
- struct _JNIEnv {
- /* do not rename this; it does not seem to be entirely opaque */
- const struct JNINativeInterface* functions;
adb shell getprop ro.product.cpu.abi
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。