Android入门笔记12

it2025-03-21  14

交叉编译

在一个平台下,编译出另一个平台能够执行的二进制的代码平台: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

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

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

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

public native String helloFromC();

在jni中定义函数实现这个方法,函数名必须为

jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)

返回一个字符串,用c定义一个字符串

char* cstr = "hello from c";

把c的字符串转换成java的字符串

jstring jstr = (*env)->NewStringUTF(env, cstr); return jstr;

在jni中创建Android.mk文件

在c文件中添加<jni.h>头文件

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

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

常见错误

findLibrary returned null

CPU平台不匹配加载类库时,写错类库名字

本地方法找不到

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

javah

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

javap

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

C向C++改造

把c文件后缀名换成cppAndroid.mk文件中的hello.c也要换成hello.cppc++的使用的环境变量结构体中,访问了c使用的结构体的函数指针,函数名全部都是一样的,只是参数去掉了结构体指针访问函数指针时,把env前面的*号去掉,因为此时env已经是一级指针clean,清除之前编译的残留文件把声明函数的h文件放入jni文件夹中,include该h文件
最新回复(0)