三、调用.a库 还可以再封装 简单
新建一个c++示例工程,复制libs和和头文件到cpp下一张图说明
一张图说明调用
四、生成.so库a.库
使用示例项目,全部默认回车,编译。
编译或者执行build make project 即可生成.so库
生成.a静态库,要改点内容
calc.cpp放在cpp下
#include <jni.h>
#include "include/calc.h"
int add(int a , int b){
return a + b;
}
calc.h放在cpp/include下
#ifndef MY_APPLICATION_CALC_H
#define MY_APPLICATION_CALC_H
int add(int a , int b);
#endif //MY_APPLICATION_CALC_H
打开CMakeLists.txt文件,将add_library下的SAHRED改为STATIC,将native-lib.cpp删掉 ,加上自己的calc.cpp
在加入build.gradle(Moudle:app)(不设这个还不行)
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-14',
'-DANDROID_TOOLCHAIN=clang'
targets 'native-lib' //看cmakelists里的模块名字
cppFlags ""
}
}
执行build make project
生成的文件位置
下面也有用ndk-build方法来生成.so库或.a库。
后面就不用看了。我走过的弯路。
涉及安全,需要把厂家提供的C语言写的.a库 再封装成.so库,再通过jni 映射给JAVA调用。
进入这里运行ndk-build
这还没加jni,下面加上jni
java10,java11删除了javah。改用javac直接用源码生成jni头文件,
javac -h 目录 源码文件
cd 目录下
javac -h .\ FTPosNatives.java
代码放在项目中编译生成.class文件(javac好像不行)
package com.example.chenhao3;
public class Dx{
public native int getdx81id();
public native int test();
}
javah生成c语言头文件 在当前目录下
javah -classpath C:\Users\wuqimei\AndroidStudioProjects\Chenhao3\app\build\intermediates\javac\debug\classes -jni com.example.chenhao3.Dx
生成的头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_chenhao3_Dx */
#ifndef _Included_com_example_chenhao3_Dx
#define _Included_com_example_chenhao3_Dx
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_chenhao3_Dx
* Method: getdx81id
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_chenhao3_Dx_getdx81id
(JNIEnv *, jobject);
/*
* Class: com_example_chenhao3_Dx
* Method: test
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_chenhao3_Dx_test
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
方法实现也写上JNIcom_example_chenhao3_Dx.c
#include <jni.h>
#include "com_example_chenhao3_Dx.h"
#include "demo.h"
JNIEXPORT jint JNICALL Java_com_example_chenhao3_Dx_getdx81id(JNIEnv *env, jobject thiz){
return getdx81id();
}
JNIEXPORT jint JNICALL Java_com_example_chenhao3_Dx_test(JNIEnv *env, jobject thiz){
return test();
}
再加入.c到android.mk后,重新编译ndk-build
.so库二次封装成功了。
二、 .so库调用
1.复制libs目录到项目下,并把目录设为jni,如图
sourceSets{
main{
jniLibs.srcDirs = ['libs']
}
}
Dx.java加到项目,注意包名不能改,并在Dx.java文件加入。再调用。
问题1:运行提示
问题2:同步了下。用真机又报这个错
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chenhao2, PID: 6516
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__read_chk" referenced by "libdemo.so"...
at java.lang.Runtime.loadLibrary(Runtime.java:365)
at java.lang.System.loadLibrary(System.java:526)
at com.example.chenhao3.Dx.<clinit>(Dx.java:5)
??????
问题3:缺x86,x86_64 这两个CPU架构
我试了,调用默认c++示例.so库是正常的,它另外带有x86,x86_64 这两个CPU架构,删了也报同样的错误 。没有使用再封装也是正常的。
说明方法是对的,只是少对应cpu架构库。所有cpu加上,x86,x86_64 报错
使用静态试试,改成static,静态x86,x86_64能编译成功。