【问题标题】:"dlopen: Invalid argument" when loading native activity加载本机活动时出现“dlopen:无效参数”
【发布时间】:2013-06-02 10:31:43
【问题描述】:

我正在使用以下引导代码来加载我的本机活动 (jngl-test):

#include <android/native_activity.h>
#include <android/log.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdexcept>

const std::string LIB_PATH = "/data/data/com.bixense.jngl_test/lib/";

void* load_lib(const std::string& l) {
    void* handle = dlopen(l.c_str(), RTLD_NOW | RTLD_GLOBAL);
    if (!handle) {
        throw std::runtime_error(std::string("dlopen(") + l + "): " + strerror(errno));
    }
    return handle;
}

void ANativeActivity_onCreate(ANativeActivity* app, void* ud, size_t udsize) {
    try {
        load_lib(LIB_PATH + "libogg.so");
        load_lib(LIB_PATH + "libvorbis.so");
        auto main = reinterpret_cast<void (*)(ANativeActivity*, void*, size_t)>(
            dlsym(load_lib(LIB_PATH + "libjngl-test.so"), "ANativeActivity_onCreate")
        );
        if (!main) {
            throw std::runtime_error("undefined symbol ANativeActivity_onCreate");
        }
        main(app, ud, udsize);
    } catch(std::exception& e) {
        __android_log_print(ANDROID_LOG_ERROR, "bootstrap", e.what());
        ANativeActivity_finish(app);
    }
}

我收到以下错误消息:

dlopen(/data/data/com.bixense.jngl_test/lib/libjngl-test.so): Invalid argument

这根本不能告诉我出了什么问题。有没有办法获得更多的调试输出? “无效参数”是什么意思?

【问题讨论】:

    标签: android c++ android-ndk dlopen native-activity


    【解决方案1】:

    我修好了:

    dlerror()
    

    提供更好的错误信息。

    如果有人感兴趣,这里是引导代码:

    #include <android/native_activity.h>
    #include <android/log.h>
    #include <dlfcn.h>
    #include <errno.h>
    #include <stdexcept>
    
    void* load_lib(const std::string& l) {
        auto handle = dlopen(std::string("/data/data/com.bixense.jngl_test/lib/" + l).c_str(),
                             RTLD_NOW | RTLD_GLOBAL);
        if (!handle) {
            throw std::runtime_error(std::string("dlopen(") + l + "): " + dlerror());
        }
        return handle;
    }
    
    void ANativeActivity_onCreate(ANativeActivity* app, void* ud, size_t udsize) {
        try {
            load_lib("libogg.so");
            load_lib("libvorbis.so");
            auto main = reinterpret_cast<void (*)(ANativeActivity*, void*, size_t)>(
                dlsym(load_lib("libjngl-test.so"), "ANativeActivity_onCreate")
            );
            if (!main) {
                throw std::runtime_error("undefined symbol ANativeActivity_onCreate");
            }
            main(app, ud, udsize);
        } catch(std::exception& e) {
            __android_log_print(ANDROID_LOG_ERROR, "bootstrap", e.what());
            ANativeActivity_finish(app);
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以这样做..
      将该库放在原始目录中并加载它
      对于原始文件,您应该考虑在 res 目录中创建一个原始文件夹,然后调用

       getResources().openRawResource(resourceName) 
      

      来自您的活动。
      然后你可以按照你喜欢的方式使用它。

      【讨论】:

      • 因为你不能像这样直接访问/data/data
      • 我可以,从stackoverflow.com/questions/12524664/… 获得代码,它适用于 libogg.so 和 libvorbis.so。
      • 与其说是“你不能”,不如说是“你不应该”。应用程序特定目录的完整路径不能保证在所有 Android 版本中都相同。如果LD_LIBRARY_PATH 没有涵盖它,您可能应该从Context.getFilesDir() 开始。
      • dlopen 会将路径视为绝对路径,如果它包含 / 如果您需要将其设置为 /data/data 目录,那么最好使用 JNI 获取此路径,这肯定会为您提供正确的路径
      猜你喜欢
      • 1970-01-01
      • 2013-01-24
      • 2012-03-21
      • 2018-12-31
      • 1970-01-01
      • 2020-07-26
      • 2013-02-01
      • 2019-05-20
      • 1970-01-01
      相关资源
      最近更新 更多