Android Studio2.2.3使用C++生成so文件

来源:互联网 发布:京瓷6525网络扫描设置 编辑:程序博客网 时间:2024/06/06 00:16

  之前的时候写过Android Studio2.2.3之前的so库文件,之前的版本的so库文件的编写详见,之前写过的文章:

http://blog.csdn.net/wb175208/article/details/52577167

当再次使用的时候,发现很多问题,之前使用已经不能成功了。原来是Android Studio升级后能很好的兼容C++,包括语法检测、自动生成函数的头文件等多种功能。自己在尝试包括在网上查找资料后,包使用方法写出来,以备之后使用。
1.创建一个工程,注意一定要勾选上这个Include C++ Support
这里写图片描述
2.一路点击 【next】点击到最后的时候,采用默认就好了:
这里写图片描述

3.点击【finish】之后,会报错:NDK not configured
这里写图片描述
4.右键点击工程名称:open moudule setting
这里写图片描述
5.把我们提前下载好的NDK,配置上去就可以了,点击【OK】
这里写图片描述
6.里面已经为我们生成了一个Demo,可以直接运行看看结果,里面有cpp,仅供参考:
这里写图片描述
还可以找到我们生成的so文件
这里写图片描述

7.但是呢,很多时候我们是不用demo的,我们需要自己手写自己的.h和.cpp文件。那我们就修改一下原来的文件。首先修改生成的so的名称和链接使用的名称:把原来的native-lib改为TestCpp
这里写图片描述
8.新建一个本地类文件TestCpp.java,并且引用我们新建的so库,红色报错也不要着急
这里写图片描述
点击Ctrl+E,选择第一个AS会自动帮我们生成实现
这里写图片描述
这里写图片描述
9.下面我们就直接测试一下看看是不是我们想要的结果。so文件我们需要release版本的。PS:(Debug版本和release版本,做个C++的都知道。debug版本是调试的使用的,里面包含很多的调试信息,文件体积也是比较大;release版本发布的时候使用的,会自动的去除掉里面的调试信息,文件体积比较小)。通过Gradle projects生成release版本:
这里写图片描述
然后在这个位置就可以找到我们的release版本的so文件
这里写图片描述
10.新建一个module来测试我们生成的so文件,然后把我们需要的so文件和TestCpp拷贝测试module中:
注意:TestCpp包名路径名必须和原来的保持一致
这里写图片描述
还需要添加这部分内容:
这里写图片描述
11.查看效果:
这里写图片描述
这样就已经到达我们需要的效果了。
12.但是C++是需要.h文件和.cpp文件配合之后的,如果我要添加新的c++类怎么办呢?
那我们就添加一个C++类:
Test.h

//// Created by aaa on 2017/4/12.//#ifndef LATINIME_TEST_H#define LATINIME_TEST_H#include <string>using namespace std;class MyTest {public:    int testAdd(int a, int b);    std::string get_str();};#endif //LATINIME_TEST_H

Test.cpp

//// Created by aaa on 2017/4/12.//#include "Test.h"std::string MyTest::get_str() {    return "asdsgfdshgf";}int MyTest::testAdd(int a, int b) {    return a + b;}

添加一个native-lib.h文件

//// Created by aaa on 2017/4/12.//#ifndef LATINIME_NATIVE_LIB_H#define LATINIME_NATIVE_LIB_H#include <jni.h>#include <string>#include "Test.h"#ifdef __cplusplusextern "C" {#endifextern MyTest gTest;JNIEXPORT jstring JNICALL        Java_com_ime_aaa_testcplus_TestCpp_testGetString(JNIEnv *env, jclass type, jstring str_);JNIEXPORT jint JNICALL        Java_com_ime_aaa_testcplus_TestCpp_testAdd(JNIEnv *env, jclass type, jint a, jint b);#ifdef __cplusplus}#endif#endif //LATINIME_NATIVE_LIB_H

native-lib.cpp

#include "native-lib.h"//定义一个全局变量MyTest gTest;/** * C字符串转java字符串 */jstring strToJstring(JNIEnv *env, const char *pStr) {    int strLen = strlen(pStr);    jclass jstrObj = env->FindClass("java/lang/String");    jmethodID methodId = env->GetMethodID(jstrObj, "<init>", "([BLjava/lang/String;)V");    jbyteArray byteArray = env->NewByteArray(strLen);    jstring encode = env->NewStringUTF("utf-8");    env->SetByteArrayRegion(byteArray, 0, strLen, (jbyte *) pStr);    return (jstring) env->NewObject(jstrObj, methodId, byteArray, encode);}/** * jstring -> UTF-8 */char *jstringToUTF8(JNIEnv *env, jstring jstr) {    char *rtn = NULL;    jclass clsstring = env->FindClass("java/lang/String");    jstring strencode = env->NewStringUTF("utf-8");    jmethodID mid = env->GetMethodID(clsstring, "getBytes",                                     "(Ljava/lang/String;)[B");    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);    jsize alen = env->GetArrayLength(barr);    jbyte *ba = env->GetByteArrayElements(barr, JNI_FALSE);    if (alen > 0) {        rtn = (char *) malloc(alen + 1);        memcpy(rtn, ba, alen);        rtn[alen] = 0;    }    env->ReleaseByteArrayElements(barr, ba, 0);    return rtn;}JNIEXPORT jstring JNICALLJava_com_ime_aaa_testcplus_TestCpp_testGetString(JNIEnv *env, jclass type, jstring str_) {    char *ch = jstringToUTF8(env, str_);    return env->NewStringUTF(ch);}JNIEXPORT jint JNICALLJava_com_ime_aaa_testcplus_TestCpp_testAdd(JNIEnv *env, jclass type, jint a, jint b) {    return gTest.testAdd(a, b);}

并且修改CMakeLists.txt文件,把我们需要编译的文件添加进去
这里写图片描述
13.重新编译so库文件,拷贝到测试的module中,并且修改TestCpp.java文件
这里写图片描述
这里写图片描述
OK!完成!

Demo下载

0 0
原创粉丝点击