背景:
一个cocos项目,安卓里面需要加一个之前打包好的so。so内为神秘的算法。so又不符合jni规则。
现有条件:
一个安卓项目,一个so库,一个h头文件。
实现思路:
1.用android studio一个新的native c++ 项目 二次封装so库。
2.native 项目中的cpp文件调用so库中的方法。
3.对外再提供符合jni规则的接口。
坑:按网上思路,各种添加so,就是编译不过去,后来发现,so是用c语言编译的。在没有so源码的情况下,只能改造native c++项目。把项目中的native-lib.cpp换成xxx.c(xxx为自定义文件名)
附报错信息,希望算法能让你我相遇
cmd.exe /C "cd . && C:\Users\vleo7\AppData\Local\Android\Sdk\ndk\16.1.4479499\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi --gcc-toolchain=C:/Users/vleo7/AppData/Local/Android/Sdk/ndk/16.1.4479499/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/vleo7/AppData/Local/Android/Sdk/ndk/16.1.4479499/sysroot -fPIC -isystem C:/Users/vleo7/AppData/Local/Android/Sdk/ndk/16.1.4479499/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=27 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a --sysroot C:/Users/vleo7/AppData/Local/Android/Sdk/ndk/16.1.4479499/platforms/android-27/arch-arm -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o D:\work2\test3\app\build\intermediates\cmake\debug\obj\armeabi-v7a\libnative-lib.so CMakeFiles/native-lib.dir/native-lib.cpp.o -llog -latomic -lm "C:/Users/vleo7/AppData/Local/Android/Sdk/ndk/16.1.4479499/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a" && cd ."
D:/work2/test3/app/src/main/cpp/native-lib.cpp:36: error: undefined reference to 'get_version(char*)'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
具体办法:
1.参考
https://cloud.tencent.com/developer/article/1655210
https://cloud.tencent.com/developer/article/1524606
其实看了好多,下边以这两个为参考做
2.新建一个
包名与cocos项目一致,符合jni规则。为了对外暴露接口。我说的不明白,可以交流哈。。。
然后next,然后再finish。。。都是默认设置就行,这里我没有做修改。
3.看这里
换成
后面主要以这个展示方式介绍和操作。。。
4.看这个,目录结构中libs文件夹,把需要引用的第三方so,放到这里
完事大概就这样,有人问我怎么复制的,复制操作的话。。。直接去文件夹里复制吧,还能咋复制。。。
第三方提供了比较四个,比较全,后面我们也出四个不同的平台版本。
5.然后就是这里,加上。
还有这里
sourceSets.main {
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}
我就有什么复制什么了。。。这里大概作用就是,回到这里看到多了一个jniLibs,里面就是刚才复制的so。
6.然后可以
clean一下。
会build。。。。安卓开发,没事就是clean。。。
7.下面就是
添加了这些
这里的wm01,是自定义的。。。与上面的所有wm01对应,你可以叫xxx。我这里用 给我的 libwm01.so 为参考。去掉lib前缀和.so后缀,为名字。。。
下面是为了方便复制:(格式问题,自己把握吧。。。别在意)
cmake_minimum_required(VERSION 3.4.1)
set(my_lib_path ${CMAKE_SOURCE_DIR}/../../../libs)
#将第三方库作为动态库引用
add_library(wm01
SHARED
IMPORTED)
#指定第三方库的绝对路径
set_target_properties(wm01
PROPERTIES IMPORTED_LOCATION
${my_lib_path}/${ANDROID_ABI}/libwm01.so)
add_library(# Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# ../jni/acc.c)
native-lib.cpp)
find_library(# Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
target_link_libraries(# Specifies the target library.
native-lib
wm01
# Links the target library to the log library
# included in the NDK.
${log-lib})
8,复制第三方so提供的.h文件
我是放到了这里,备用,你们可以根据自己的习惯调整,后面有一个自己写的.h文件,需要引用。路径不同罢了。
9.建一个自己的点.c和.h文件。
那么问题来了,c怎么写的呢,jni规则呗,先写java类,然后利用java类,生成.h,头文件里就有c里面的方法名。大概思路。
下面一点点来。先建一个JniUtils.java 这个类名注意记住,其他项目引用现在的项目打包出来的so也会用到。jni标准嘛。这个自己可以百度了,我就不写了。。。
这里红色,先不用管,直接build。
图中第三步,make一下。图中2部分,会有变化。
然后,找到
直接到文件夹查看。主要是获取这个路径。
我这里是
D:\work818\testCocos\app\build\intermediates\javac\debug\classes\org\cocos2dx\javascript
然后,把上面的形式,改成:
D:\work818\testCocos\app\build\intermediates\javac\debug\classes org.cocos2dx.javascript.JniUtils
然后就是,打开
然后定位到main目录
然后 复制下面的命令
javah -d jni -classpath D:\work818\testCocos\app\build\intermediates\javac\debug\classes org.cocos2dx.javascript.JniUtils
执行完,是这样
这个位置,会多一个jni。。我只是跟着别人走。。会把自己自定义的c和h放到这里。有兴趣可以看看javah命令,可以自己生成h头文件后,复制到项目里也行。
10.改一下文件名。我随便先起一个吧。
这里就是c里面的方法,再看下c
就这样。
是不是有很多红色,回到刚才
先改成这样
然后回到c文件中,点击右上角 Sync now
就可以了
这个是完整版
这里也不红色了
然后删掉
在build试试,make试试,然后找到
解压里面的lib文件夹,就是我们想要的。。里面会有两个so
。。
11.如何使用给个图吧,一看就懂。
这里加一句。
如果JniUtils中出现红色。看下面