“dlopen: Invalid argument” when loading native act

2019-08-28 01:46发布

I'm using the following bootstrapping code to load my native activity (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);
    }
}

I get the following error message:

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

This doesn't tell me at all whats going wrong. Is there a way to get more debug output? What could "Invalid argument" mean?

2条回答
我想做一个坏孩纸
2楼-- · 2019-08-28 01:50

I fixed it:

dlerror()

gives a far better error message.

Here's the bootstrap code if someone is interested:

#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);
    }
}
查看更多
一纸荒年 Trace。
3楼-- · 2019-08-28 02:04

You could do this..
put that lib in raw directory and load it
For raw files, you should consider creating a raw folder inside res directory and then call

 getResources().openRawResource(resourceName) 

from your activity.
then you can use it the way you like.

查看更多
登录 后发表回答