我目前正在开发一个具有 C++ 集成的小型演示 Android 应用程序。我使用的是 Android Studio 3.1.4,我的项目支持 NDK(开发环境是Windows 10)。应用程序的目的是从存储(sdcard)加载共享库(.so)文件,然后动态链接库。以下是我创建此应用程序所经历的步骤:1.在Cygwin上使用GCC生成共享库这些是我用来编译库的文件“sumLib.h”:#define _MYLIB_H_#define MAX_INPUT 25extern double sum(double x, double y);“sumLib.c”:#include <stdlib.h>#include "sumLib.h"double sum(double x, double y) { return x + y;}然后我使用以下这些命令来生成库文件:gcc -shared -o sumLib.o -c sumLib.cgcc -shared -o sumLib.so sumLib.o2.在Android客户端加载库文件我将文件传输到 Android 模拟器的 sd 卡中(使用 Device File Explored)(/storage/emulated/0/Download/sumLib.so)这是读取库并将其与符号“sum”链接的 C++ 代码:extern "C" {JNIEXPORT jdouble JNICALLJava_com_example_user_demo_MainActivity_sum(JNIEnv *env, jobject obj, jdouble n1, jdouble n2) { void *handle; double (*sum)(double, double); char *error; char fname[PATH_MAX]; strcpy(fname, internalPath); //internal path is a predefined string that points to the Download folder in the SD card strcat(fname, "/sumLib.so"); handle = dlopen(fname, RTLD_LAZY); if (!handle) { __android_log_write(ANDROID_LOG_ERROR, "Creating handle", "Error creating handle"); exit(EXIT_FAILURE); }这理论上应该调用用c++定义的“sum”函数并使用库查找符号“sum”并执行操作,但是dlopen无法从文件创建句柄,它不断抛出错误。这是错误消息:"dlopen failed: library \"/storage/emulated/0/Download/sumLib.so\" needed or dlopened by \"/data/app/com.example.user.demo-fzNLN7tBu86LCNun1yLQlg==/lib/x86_64/libnative-lib.so\" is not accessible for the namespace \"classloader-namespace\""我注意到在错误消息中文件地址的末尾,他们添加了一个正斜杠而不是反斜杠,这有什么影响吗?另外我不确定错误消息的后半部分是什么意思。我认为,在Cygwin GCC可能在不同的体系结构来编译什么Android模拟器上运行,但经过我检查了文件,我发现它编译为64位(根据这个,我发现PE d +从阅读文件)。对于模拟器,我正在运行 x86_64 图像(API 27)并在我调用后打印出x86_64:String arch = System.getProperty("os.arch");Log.d("Debug", String.format("system arch is %s", arch));我还检查了该文件是否可以从 c++ 环境访问,所以我使用了FILE *f = fopen(fname, "r");并且在调试器中,它没有指向 null,而是指向某个东西,准确地说是0x00007227dd414018,假设它找到了文件并且可以正确读取它是否安全?它能够正确打开库、链接符号并返回正确的结果。我做错了什么导致dlopen抛出该错误?
1 回答
白衣染霜花
TA贡献1796条经验 获得超10个赞
尝试为目标 SDK 23 或更低版本构建您的应用程序,并在模拟器 API 24 或更低版本上运行它。我相信你看到的失败是最近安全措施的体现。请参阅Android 7.0 行为更改:
从 Android 7.0 开始,系统会阻止应用动态链接非 NDK 库。
使用主机gcc编译器构建sumLib.so 也无济于事。即使生成的库针对相同的x86_64 ABI,Android 上的运行时环境也完全不同。请使用 NDK 工具链。如果您愿意,可以使用独立工具链而不是ndk-build或CMake脚本。
添加回答
举报
0/150
提交
取消