如何本地运行时库与NDK的dlopen集成? [英] How to integrate native runtime library with dlopen on NDK?

查看:159
本文介绍了如何本地运行时库与NDK的dlopen集成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关我的本地C ++项目,我已经成立了$ P $的运行时加载pcompiled共享库,这可以通过客户端使用配置的启动来改变。什么是Android上调用的dlopen的正确方法?无论我做什么,的dlopen不能打开任何共享库,如果我没有在我的Andr​​oid.mk定义这个库precompiled库文件是这样的:

For my native c++ project I've to set up a runtime loading of a precompiled shared library, which could be changed by client side on start up using configurations. What is the proper way of calling dlopen on android? No matter what I do, dlopen can never open any shared library, if I not define this library as precompiled library in my Android.mk file like this:

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)

在我的祖国活动的主类我尝试加载库:

In my native activity main class I try to load the library with:

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

这个实现的disadventage是不是一个真正的运行时加载,因为我用JAVA机制来加载该库还对JNI启动。

The disadventage of this implementation is that is not really a runtime loading, because I've to load this library also on JNI startup using JAVA mechanisms.

如果我删除Android.mk酒吧库precompile defintions,在启动时禁用JNI加载并添加precompiled库到系统/ lib文件夹,它应该是一个副本(同一地方,它使用precompile定义存储),库的加载失败。我检查它包含我的预期lib文件夹手动复制库中的APK包。

If I remove the bar library precompile defintions from Android.mk, disable JNI loading on startup and add a copy of the precompiled library to the systems/lib folder where it should be (same place where it is stored using precompile definitions), the loading of the library fails. I've checked the apk package it contains my manually copied library at lib folder as expected.

为什么这是不行的?是否有可能执行外部precompiled库的严格本地运行时库加载?什么是保证我的库添加到APK包的最佳方法是什么?

Why this will not work? Is it possible to perform a strict native runtime library loading of an external precompiled library? And what is the best way to ensure that my library is added to the apk package?

推荐答案

在Android的最佳策略是加载从Java所有的本地库,即使您选择哪个库加载,被一些运行规则。您可以使用的dlsym(0,...),然后访问导出的函数存在。

The best strategy on Android is to load all native libraries from Java, even if you choose which libraries to load, by some runtime rules. You can use dlsym(0, ...) then to access exported functions there.

APK建设者将拿起所有的的.so 文件发现的库/ armeabi-V7A 键,安装程序会解压成 /data/data/<your.package>/lib 目录。

APK builder will pick up all .so files it finds in libs/armeabi-v7a and the installer will unpack them into /data/data/<your.package>/lib directory.

这篇关于如何本地运行时库与NDK的dlopen集成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆