当前位置:   article > 正文

android NDK开发学习之Jni(一)_android jni开发

android jni开发

JNI是什么?

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文件的对应签名类型

android studio 开发jni开发

1、创建C++ 工程 

2、导入C/C++文件

3、java/kotlin加载C/C++代码

 

 

调用规则

c++文件

native.cpp

  1. #include <jni.h>
  2. #include <string>
  3. //extern "C" :下边的代码采用C的编译方式
  4. //JNIEXPORT:JNI重要标记关键字,不能少(VS编译能通过,运行会报错) / (AS 运行不会报错), 规则(标记为该方法可以被外部调用) Windows内部规则,与Linux内部规则 不同
  5. //jstring:代表 java 中的 String
  6. //JNICALL : 也是一个关键字,(可以少的) jni call (约束函数入栈顺序,和堆栈内存清理的规则)
  7. //jobject: java传递下来的对象,就是本项目中 MainActivity 对象
  8. extern "C" JNIEXPORT jstring JNICALL
  9. // 规则:
  10. //Java_包名(以_连接,如果原包名中有下划线则表示1)_类名_方法名
  11. Java_com_wangyb_c_1xiangxue_1project_MainActivity_stringFromJNI(
  12. JNIEnv* env,
  13. jobject /* this */) {
  14. std::string hello = "Hello from C++";
  15. // 如果是c文件 native-lib.c
  16. //JNIEnv* env 是二级指针,使用时需要通过(*env)-> 调用
  17. return env->NewStringUTF(hello.c_str());
  18. }
  19. //jclass :java传递下来的 class 对象,就是本项目中的 MainActivity class
  20. extern "C" JNIEXPORT void JNICALL
  21. Java_com_wangyb_c_1xiangxue_1project_MainActivity_changeName(JNIEnv* env,jobject obj) {
  22. // 如果是c++文件 native-lib.cpp
  23. //JNIEnv* env 是一级指针,使用时可直接调用env->,调用原理如下
  24. // 1.修改name
  25. jclass mainActivityCls = env->GetObjectClass(obj);
  26. jfieldID name_fid = env->GetFieldID(mainActivityCls, "name","Ljava/lang/String;");
  27. jstring value = env->NewStringUTF("李老八");
  28. env->SetObjectField(obj, name_fid, value);
  29. //如果在c中,c是没有对象的,想持有env环境必须传入进去
  30. jstring value = (*env)->NewStringUTF(env,"李老八");
  31. }

c文件

native.c

  1. #include <jni.h>
  2. //#include <string>
  3. //extern "C" :下边的代码采用C的编译方式
  4. //JNIEXPORT:JNI重要标记关键字,不能少(VS编译能通过,运行会报错) / (AS 运行不会报错), 规则(标记为该方法可以被外部调用) Windows内部规则,与Linux内部规则 不同
  5. //jstring:代表 java 中的 String
  6. //JNICALL : 也是一个关键字,(可以少的) jni call (约束函数入栈顺序,和堆栈内存清理的规则)
  7. //jobject: java传递下来的对象,就是本项目中 MainActivity 对象
  8. //extern "C"
  9. JNIEXPORT jstring JNICALL
  10. // 规则:
  11. //Java_包名(以_连接,如果原包名中有下划线则表示1)_类名_方法名
  12. Java_com_wangyb_c_1xiangxue_1project_MainActivity_stringFromJNI(
  13. JNIEnv* env,
  14. jobject obj) {
  15. // std::string hello = "Hello from C++";
  16. // 如果是c文件 native-lib.c
  17. //JNIEnv* env 是二级指针,使用时需要通过(*env)-> 调用
  18. return (*env)->NewStringUTF(env,"Hello from C++");
  19. }
  20. //jclass :java传递下来的 class 对象,就是本项目中的 MainActivity class
  21. //extern "C"
  22. JNIEXPORT void JNICALL
  23. Java_com_wangyb_c_1xiangxue_1project_MainActivity_changeName(JNIEnv* env,jobject obj) {
  24. // 如果是c++文件 native-lib.cpp
  25. //JNIEnv* env 是一级指针,使用时可直接调用env->
  26. // 1.修改name
  27. jclass mainActivityCls = (*env)->GetObjectClass(env,obj);
  28. jfieldID name_fid = (*env)->GetFieldID(env,mainActivityCls, "name","Ljava/lang/String;");
  29. jstring value = (*env)->NewStringUTF(env,"李老八");
  30. (*env)->SetObjectField(env,obj, name_fid, value);
  31. }

原理

jni.h文件中

  1. struct _JNIEnv;
  2. struct _JavaVM;
  3. typedef const struct JNINativeInterface* C_JNIEnv;
  4. //此处表示是c++
  5. #if defined(__cplusplus)
  6. //JNIEnv是别名,所以JNIEnv* env是一级指针
  7. typedef _JNIEnv JNIEnv;
  8. typedef _JavaVM JavaVM;
  9. #else
  10. //此处表示c 。JNINativeInterface* JNIEnv是一个一级指针。所以JNIEnv* env是二级指针(形参 *xxx 已经是一个二级指针了),调用时需要(*env)
  11. typedef const struct JNINativeInterface* JNIEnv;
  12. typedef const struct JNIInvokeInterface* JavaVM;
  13. #endif
  14. struct _JNIEnv {
  15. /* do not rename this; it does not seem to be entirely opaque */
  16. const struct JNINativeInterface* functions;

查看 手机设备cpu架构 adb命令

adb shell getprop ro.product.cpu.abi

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/575216
推荐阅读
相关标签
  

闽ICP备14008679号