我目前正在开发一个具有 C++ 集成的小型演示 Android 应用程序。我使用的是 Android Studio 3.1.4,我的项目支持 NDK(开发环境是Windows 10)。
应用程序的目的是从存储(sdcard)加载共享库(.so)文件,然后动态链接库。
以下是我创建此应用程序所经历的步骤:
1.在Cygwin上使用GCC生成共享库
这些是我用来编译库的文件
“sumLib.h”:
#define _MYLIB_H_
#define MAX_INPUT 25
extern 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.c
gcc -shared -o sumLib.so sumLib.o
2.在Android客户端加载库文件
我将文件传输到 Android 模拟器的 sd 卡中(使用 Device File Explored)(/storage/emulated/0/Download/sumLib.so)
这是读取库并将其与符号“sum”链接的 C++ 代码:
extern "C" {
JNIEXPORT jdouble JNICALL
Java_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抛出该错误?
白衣染霜花
相关分类