JNI与底层调用01

交叉编译

  • 在一个平台下,编译出另一个平台能够执行的二进制的代码
  • 平台:windows,mac os,linux
  • 处理器:x86,arm,mips

交叉编译的原理

  • 源代码->编译->链接->可执行程序
  • 模拟其他平台的特性

交叉编译的工具链

  • 多个工具的集合,一个工具使用完后接着调用下一个工具

常见工具

  • NDK:native developement kit:开发jni必备,就是模拟其他平台特性来编译代码的工具
  • CDT:C/C++ developement tools:高亮显示c语言关键字
  • cygwin:一个模拟器,可以再windows下运行linux指令

NDK目录结构

  • docs:帮助文档
  • build/tools:linux的批处理文件
  • platforms:编译c代码需要使用的头文件和类库
  • prebuilt:预编译使用的二进制可执行文件
  • sample:jni的使用例子
  • source:ndk的源码
  • toolchains:工具链
  • ndk-build.cmd:编译打包c代码的一个指令

使用jni

  1. 在项目根目录下创建jni文件夹

  2. 在jni文件中创建一个c文件

  3. 在java代码中,创建一个本地方法helloFromC

     public native String helloFromC();
    
  4. 在jni中定义函数实现这个方法,函数名必须为

     jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
    
  5. 返回一个字符串,用c定义一个字符串

     char* cstr = "hello from c";
    
  6. 把c的字符串转换成java的字符串

     jstring jstr = (*env)->NewStringUTF(env, cstr);
     return jstr;
    
  7. 在jni中创建Android.mk文件

  8. 在c文件中添加头文件

  9. 在jni文件夹下执行ndk-build.cmd指令

  10. java代码中加载so类库,调用本地方法

常见错误

  • findLibrary returned null

    • CPU平台不匹配
    • 加载类库时,写错类库名字
  • 本地方法找不到

    • 忘记加载类库
    • c代码中方法名写错了

javah

*1.7:在src目录下执行javah 包名.类名
*1.6:在bin/classes目录下执行

javap

  • 在bin/class目录下执行javap -s 包名.类名
    • 打印方法签名

你可能感兴趣的:(JNI与底层调用01)