如何在Native层加载so库

在Native层加载so库

HarmonyOS
2024-05-28 21:46:52
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
路易不知第几世

在Native层的C/C++代码环境,so库动态加载是使用dlopen()、dlsym()和dlclose()这三个函数实现的。它们的作用分别是:

  • dlopen()打开一个动态链接库,返回一个动态链接库的句柄;
  • dlsym()根据动态链接库句柄和符号名,返回动态链接库内的符号地址,这个地址既可以是变量指针,也可以是函数指针;
  • dlclose()关闭动态链接库句柄,并对动态链接库的引用计数减1,当这个库的引用计数为0,这个库将会被系统卸载。

一般使用C/C++实现so库动态加载,流程如下:

首先调用dlopen()函数,这个函数所需的参数,一个是so库的路径,一个是加载模式。一般使用的加载模式有两个:

  • RTLD_NOW在返回前解析出所有未定义符号,如果解析不出来,dlopen()返回NULL;
  • RTLD_LAZY则只解析当前需要的符号(只对函数生效,变量定义仍然是全部解析)。

显然对于动态加载,加载方只需知道当前被加载的so库里面自己需要用的函数和变量定义,所以这里选择的是后者。如果这个调用成功将返回一个so库的句柄;

在上一步得到so库句柄之后,这时就可以调用dlsym()函数,传入so库句柄和所需的函数或变量名称,返回相应的函数指针或变量指针;加载方这时就可以使用返回的指针调用被加载so库之中定义的函数和数据结构;

当so库的调用结束,调用dlclose()函数关闭卸载so库;

如果在打开关闭so库,或者获取so库里操作对象的指针出现错误的时候,可以调用dlerror()函数获取具体的错误原因。

Native侧代码实现

<CMakeLists.txt> 
 
# the minimum version of CMake. 
cmake_minimum_required(VERSION 3.4.1) 
project(OpenCl) 
include_directories(${CMAKE_SOURCE_DIR}/include) 
link_directories(${CMAKE_SOURCE_DIR}/libs) 
add_library(entry SHARED hello.cpp) 
target_link_libraries(entry libace_napi.z.so libhilog_ndk.z.so) 
<hello.cpp> 
 
#include "napi/native_api.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <dlfcn.h> 
#define LOG_TAG "name1111111111" 
#include <hilog/log.h> 
 
  //add接口,里面写对应的业务逻辑 
  static napi_value Add(napi_env env, napi_callback_info info) 
{ 
  size_t requireArgc = 2; 
  size_t argc = 2; 
  napi_value args[2] = {nullptr}; 
 
  napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 
 
  napi_valuetype valuetype0; 
  napi_typeof(env, args[0], &valuetype0); 
 
  napi_valuetype valuetype1; 
  napi_typeof(env, args[1], &valuetype1); 
 
  double value0; 
  napi_get_value_double(env, args[0], &value0); 
 
  double value1; 
  napi_get_value_double(env, args[1], &value1); 
 
  napi_value sum; 
  napi_create_double(env, value0 + value1, &sum); 
 
  int a, b; 
  void *p; 
  int (*func)(int, int); 
  scanf("%d%d", &a, &b); 
  // dlopen两个参数,第一个是想要打开的so库路径,第二个参数是加载模式 
  p = dlopen("/vendor/lib64/libnpu_slog.so", RTLD_NOW | RTLD_LOCAL); 
  if (p == NULL) { 
    OH_LOG_INFO(LOG_APP, "dlopenNull: dlopen error!"); 
    exit(0); 
  } else 
    OH_LOG_INFO(LOG_APP, "dlopenSuccess: dlopen ok!"); 
  dlclose(p); 
  return sum; 
} 
 
//导出add接口 
EXTERN_C_START 
static napi_value Init(napi_env env, napi_value exports) 
{ 
  napi_property_descriptor desc[] = { 
  { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr } 
}; 
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 
return exports; 
} 
EXTERN_C_END 
 
static napi_module demoModule = { 
  .nm_version = 1, 
  .nm_flags = 0, 
  .nm_filename = nullptr, 
  .nm_register_func = Init, 
  .nm_modname = "entry", 
  .nm_priv = ((void*)0), 
  .reserved = { 0 }, 
}; 
 
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) 
{ 
  napi_module_register(&demoModule); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
分享
微博
QQ
微信
回复
2024-05-29 23:06:32


相关问题
ArkTS侧与Native侧分别如何动态加载SO
3185浏览 • 1回复 待解决
ArkTS和Native如何动态加载、卸载so
2536浏览 • 1回复 待解决
如何在native获取屏幕亮度
2238浏览 • 1回复 待解决
如何在ArkTS中动态加载so
1186浏览 • 1回复 待解决
Native如何集成三方SO
2926浏览 • 1回复 待解决
如何在HarmonyOS app使用so
443浏览 • 1回复 待解决
Native工程中如何使用其他三方so
3057浏览 • 1回复 待解决
ArkTS中如何使用编译出来的Native so
819浏览 • 1回复 待解决
c编译的so,导出成native的har静态
738浏览 • 1回复 待解决
Native so 编译 opencv,报找不到 libunwind.so
1554浏览 • 1回复 待解决
HarmonyOS nativejs代码调用
529浏览 • 1回复 待解决
ArkTS项目如何调用已有SO?
1466浏览 • 1回复 待解决
native创建socket异常
969浏览 • 1回复 待解决
HarmonyOS native文件读写权限
550浏览 • 1回复 待解决
HarmonyOS 如何适配自己的so
1134浏览 • 1回复 待解决