Hel*_*und 6 android android-ndk
对于我的本机c ++项目,我将设置预编译共享库的运行时加载,可以在启动时使用配置由客户端更改.什么是在Android上调用dlopen的正确方法?无论我做什么,dlopen永远不会打开任何共享库,如果我没有在我的Android.mk文件中将此库定义为预编译库,如下所示:
LOCAL_PATH := $(call my-dir)
LOCAL_CFLAGS += -DDEBUG
LOCAL_CFLAGS += -DANDROID
include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar/bar.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/bar
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := native_activity
LOCAL_SRC_FILES := main.cpp
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += -landroid
LOCAL_SHARED_LIBRARIES := bar
LOCAL_STATIC_LIBRARIES += android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
$(call import-module, android/native_app_glue)
Run Code Online (Sandbox Code Playgroud)
在我的本机活动主类中,我尝试加载库:
void* lib = dlopen("/system/lib/armeabi-v7a/libbar.so", RTLD_NOW);
if (lib == NULL) {
fprintf(stderr, "Could not dlopen(\"libbar.so\"): %s\n",
dlerror());
exit(1);
}else{
LOGI("Library successfully loaded!");
if (dlsym(lib, "bar") == NULL) {
fprintf(stderr, "Symbol 'bar' is missing from shared library!!\n");
}else{
LOGI("Library symbol found!");
}
int x = bar(25);
LOGI("Bar return value: %i", x);
}
Run Code Online (Sandbox Code Playgroud)
这种实现的缺点是实际上并不是运行时加载,因为我还要使用JAVA机制在JNI启动时加载这个库.
如果我从Android.mk中删除了bar库预编译定义,请在启动时禁用JNI加载,并将预编译库的副本添加到应该存在的systems/lib文件夹中(使用预编译定义存储它的位置相同),加载库失败了.我检查了apk包,它包含我在lib文件夹中手动复制的库,如预期的那样.
为什么这不起作用?是否可以执行外部预编译库的严格本机运行时库加载?确保我的库添加到apk包的最佳方法是什么?
Ale*_*ohn 12
Android上的最佳策略是从Java加载所有本机库,即使您根据某些运行时规则选择要加载的库.您可以使用dlsym(0,...)然后访问那里的导出函数.
APK构建器将获取它找到的所有.so文件,libs/armeabi-v7a安装程序将解压缩到/data/data/<your.package>/lib目录中.
| 归档时间: |
|
| 查看次数: |
13193 次 |
| 最近记录: |