「这是我参与2022首次更文挑战的第29天,活动详情查看:2022首次更文挑战」。
上一章节介绍了如何配置so文件需要的开发环境,今天这一章节主要介绍,如何将C++代码编译成so文件。
看过我之前文章的都知道,其实我是一个地地道道的C++开发程序猿,因为同事离职,他负责的so文件编译的重担就放到了我身上,责任重大呀!
今天我就来讲解下我是如何一步一步以C++开发程序员的角度创建并调用so文件的,适合跟我一样的小白。
java环境与Android环境上一章节中有介绍,这里不再过多说明了。
1:创建so文件的工程
按照图片指示,创建一个新工程,此时会出现以下这个界面
选择最后一个:Native C++
点击下一步之后出现下图页面
页面说明:
Name:项目名称,这个随意声明。
Package name:包名称。
其实我刚开始做的时候以为这个名称就是固定的,结果,后来才发现,这是可以修改的,简直了!!
配置好该页面后,直接点击右下角的“Finish”,项目就算建好了。
如果是这样的,说明项目跟我建立的是一致的。记得需要用Project查看才是这样的。
在开发过程中,安卓想要调用C++代码是不能直接调用的,这时,就需要一个中间键来通信,在上述图片汇总,“native-lib.cpp”这就是两个不同平台的中间键代码,编译的最终so文件也是调用的"native-lib.cpp"中的函数内容。
默认的native-lib内容如下:
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_st_hellworld_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
刚开始看到这个文件的时候,我简直都懵了,怎么会有这么长的函数名,这个函数名这么定义有什么意义呢?
研究了好长时间我才知道,Android调用还真是挺严谨的!
函数名:Java_com_st_hellworld_MainActivity_stringFromJNI进行讲解
看到图片上用蓝色框出来的区域,这是这个调用函数的函数名的意思,是在java文件夹下,com文件夹下,st文件夹下,helloworld文件夹下的MainActivity类中的 stringFromJNI函数的中间键说明。
那么,我们来看一下MainActivity文件
想要哪个函数与C++通信,那么哪个函数前面就需要有"native"字样表示。
在图片中蓝色区域选中的stringFromJNI函数是需要生成so文件被调用的。
2:编译so文件
选中Make Project直接编译"Hello World"项目,编译完成之后会在app中出现一个build文件,如图所示
蓝色区域内就是生成的so的位置。
到这里,不改变任何代码就可以直接生成简单的so文件。
3:使用so文件
上述编译完成后,接下来是该如何使用编译好的so文件。
3.1:创建一个新Android Studio项目
这里,选中"Empty Activity"类型创建项目,名称随意定义,假设叫做:UseAndroidTest1
3.2:项目中配置so文件
第一步
在app->src->main中创建一个叫做:jniLibs文件夹,这里存放的是 cmake编译的so文件,如图所示
第二步
修改app文件夹下的"build.gradle",改成如图所示内容
此时,so文件所需的内容就已经配置完成了,
3.3:调用so文件中的API
这也是最最容易出错,也是最不容易发现错误的地方了。
在中间键文件:native-lib.cpp中,有一个默认的函数,函数名是:Java_com_st_hellworld_MainActivity_stringFromJNI
当我们在调用so的位置也需要按照so中函数名的方式创建一个一模一样的路径,并且类名叫做:MainActivity,有一个叫做stringFromJNI的函数,只有这样才会调用成功。
在st下面创建一个与so函数中层级一样的文件夹
只有这样将,在helloword中MainActivity调用stringFromJNI函数才会成功,否则会出错!
我是中国好公民st,一名C++开发程序猿~