gpt4 book ai didi

android - 如何在 NDK 上将 native 运行时库与 dlopen 集成?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:35:24 24 4
gpt4 key购买 nike

对于我的 native c++ 项目,我必须设置预编译共享库的运行时加载,客户端可以在启动时使用配置更改它。在 android 上调用 dlopen 的正确方法是什么?无论我做什么,如果我没有像这样在我的 Android.mk 文件中将此库定义为预编译库,dlopen 永远无法打开任何共享库:

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)

在我的本地 Activity 主类中,我尝试使用以下方法加载库:

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);
}

这个实现的缺点是它不是真正的运行时加载,因为我还必须使用 JAVA 机制在 JNI 启动时加载这个库。

如果我从 Android.mk 中删除 bar 库预编译定义,禁用启动时的 JNI 加载并将预编译库的副本添加到它应该在的 systems/lib 文件夹中(与使用预编译定义存储它的位置相同) ,库加载失败。我已经检查了 apk 包,它包含我在 lib 文件夹中手动复制的库,如预期的那样。

为什么这行不通?是否可以对外部预编译库执行严格的 native 运行时库加载?确保将我的库添加到 apk 包中的最佳方法是什么?

最佳答案

Android 上的最佳策略是从 Java 加载所有 native 库,即使您根据某些运行时规则选择要加载的库也是如此。您可以使用 dlsym(0, ...) 然后在那里访问导出的函数。

APK 构建器将选取它在 libs/armeabi-v7a 中找到的所有 .so 文件安装程序会将它们解压到 /data/data/<your.package>/lib 中目录。

关于android - 如何在 NDK 上将 native 运行时库与 dlopen 集成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15719149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com