讨论广场 问答详情
将so库加入到工程中,在ArkTS侧将so库的沙箱路径传递至Native侧,在Native侧使用dlopen解析so库调用功能函数。有没有相关代码可以实现这个功能呢?
aurora6688 2026-08-23 01:01:16
54 评论 分享
harmonyos

为保障用户隐私安全,dlopen具有命名空间隔离能力,应用可以加载的动态库受到命名空间的限制。我在学习鸿蒙中,遇到了一个问题怎么理解呢?

54 评论 分享
写回答
全部评论(1)

通过调用dlopen的方式引用

实现原理

将so库加入到工程中,在ArkTS侧将so库的沙箱路径传递至Native侧,在Native侧使用dlopen解析so库调用功能函数。但是需要注意,该方案只能引用C语言编译模式生成的so库,因此用于生成so库的.h头文件需要用extern "C" {}包裹。

此处需要使用so库的沙箱路径,而不是其真实路径。

为保障用户隐私安全,dlopen具有命名空间隔离能力,应用可以加载的动态库受到命名空间的限制。一般应用只能够加载应用安装包目录/data/storage/el1/bundle下的动态库,以及系统内置对外开放的动态库,若加载自定义路径动态库会报错:MUSL-LDSO bundlename E Open absolute_path library: check ns accessible failed, pathname libxxx.so namespace moduleNs_default。

let projectPath = this.getUIContext().getHostContext()!.bundleCodeDir; // Get the project path
let abiPath = deviceInfo.abiList === 'x86_64' ? 'x86_64' : 'arm64';
let soLibPath = `${projectPath}/libs/${abiPath}/libnativeSub.so`;

在Native侧引入dlfcn.h,通过调用dlopen解析so库实现减法计算。

typedef double (*Sub)(double, double);
static napi_value NAPI_Global_nativeSub(napi_env env, napi_callback_info info) {
    size_t argc = 3;
    napi_value args[3] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    double value0;
    napi_get_value_double(env, args[0], &value0);
    double value1;
    napi_get_value_double(env, args[1], &value1);
    size_t length = 0;
    napi_status status = napi_get_value_string_utf8(env, args[2], nullptr, 0, &length);
    if (status != napi_ok) {
        return nullptr;
    }
    char *path = new char[length + 1];
    std::memset(path, 0, length + 1);
    napi_get_value_string_utf8(env, args[2], path, length + 1, &length); // Get the SO library path information
    void *handle = dlopen(path, RTLD_LAZY);                              // Open a SO library and get the path
    napi_value result = nullptr;
    Sub sub_func = (Sub)dlsym(handle, "sub"); // Get the function named sub
    status = napi_create_double(env, sub_func(value0, value1), &result);
    delete[] path;
    dlclose(handle); // Remember to close the SO library
    if (status != napi_ok) {
        return nullptr;
    }
    return result;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        // ...
        {"nativeSub", nullptr, NAPI_Global_nativeSub, nullptr, nullptr, nullptr, napi_default, nullptr}};
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

 

2026-08-23 01:02:51