OpenHarmony开发者论坛

标题: 如何使用napi加载并调用现有的so库接口 [打印本页]

作者: HeavenGo    时间: 2024-12-20 17:01
标题: 如何使用napi加载并调用现有的so库接口
[md]### 【问题描述】

1. 介绍问题现象和发生的背景
   我有一个第三方libohostest.so库(基于OpenHarmony编译链编出来的动态库,不是在DevEchoStudio上编译生成)简单实现了加法,需要在DevEchoStudio实现加载并调用加法的接口。因为论坛和官网上提供的示例一般都是基于NativeC++编译so或者导入module编译出so,没有看到对现有so库的加载调用,由于刚接触OpenHarmony,调试的比较费劲。简单写了个OpenHarmony Empty Ability项目(非Native C++项目),so库放在entry/libs/arm64-v8a下,main目录下手动创建cpp目录,include目录下放so库的头文件,napi目录下放test_interface.cpp的napi文件,cpp目录下放CMakeLists.txt文件,Index.ets中导入napi封装的libohostest.so库并调用,但是提示napi提供的addsum方法找不到
2. 相关的代码(请勿使用截图)

   Index.ets代码如下:

   ```


   import libohostest from 'libohostest.so';

   @Entry
   @Component
   struct Index {
     @State message: string = '2+3=?';

     build() {
       Row() {
         Column() {
           Text(this.message)
             .fontSize(50)
             .fontWeight(FontWeight.Bold)
             .onClick(() => {
               const result:number = libohostest.addsum(2, 3)
               console.info("result:" + result)
               this.message = '2+3=' + result
             })
         }
         .width('100%')
       }
       .height('100%')
     }
   }
   ```

   Cmakelists.txt文件:

   ```
   cmake_minimum_required(VERSION 3.4.1)
   project(nexui)

   set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})

   # 添加头文件路径
   include_directories(${NATIVERENDER_ROOT_PATH}
                      ${NATIVERENDER_ROOT_PATH}/include)

   link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/arm64-v8a)

   # 创建共享库
   add_library(testinterface SHARED napi/test_interface.cpp)

   # 链接需要的库
   target_link_libraries(testinterface PUBLIC
                        libace_napi.z.so
                        libhilog_ndk.z.so
                        libohostest.so
                        libc.so
                        libdl.so)
   ```

   test_interface.cpp代码如下:

   ```
   #include <napi/native_api.h>
   #include <dlfcn.h>
   #include "native_api.h"

   #define LOG_TAG "TestInterface"

   // 定义函数指针类型,假设test.so中的加法函数接收两个int参数并返回int
   typedef int (*AddFunction)(int, int);

   static napi_value Add(napi_env env, napi_callback_info info)
   {
       // libohostest.so库
       void* handle = dlopen("libohostest.so", RTLD_LAZY);
       if (!handle) {
           napi_throw_error(env, nullptr, "Failed to load library");
           return nullptr;
       }

       // 获取add函数指针
       AddFunction addFunc = (AddFunction)dlsym(handle, "get_sum");
       if (!addFunc) {
           dlclose(handle);
           napi_throw_error(env, nullptr, "Failed to get function pointer");
           return nullptr;
       }

       // 获取参数
       size_t argc = 2;
       napi_value args[2];
       napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

       // 检查参数数量
       if (argc < 2) {
           dlclose(handle);
           napi_throw_error(env, nullptr, "Wrong number of arguments");
           return nullptr;
       }

       // 转换参数
       int32_t value1, value2;
       napi_get_value_int32(env, args[0], &value1);
       napi_get_value_int32(env, args[1], &value2);

       // 调用so库中的add函数
       int result = addFunc(value1, value2);

       // 关闭库
       dlclose(handle);

       // 返回结果
       napi_value returnValue;
       napi_create_int32(env, result, &returnValue);
       return returnValue;
   }

   EXTERN_C_START
   static napi_value Init(napi_env env, napi_value exports) {
       napi_property_descriptor desc[] = {
           {"addsum", 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 = "testinterface",
       .nm_priv = ((void *)0),
       .reserved = {0},
   };

   extern "C" __attribute__((constructor)) void RegisterEntryModule(void) {
       napi_module_register(&demoModule);
   }
   ```

   so库的头文件

   ```
   #ifndef __OHOSTEST__
   #define __OHOSTEST__

   int get_sum(int a, int b);

   #endif
   ```
3. 运行结果、错误截图

   Error message: Cannot read property addsum of undefined
4. 我尝试过的解决方法和结果

   尝试新建Native C++项目的方式使用napi接口,并修改加载so库的方式来加载方法,但是编译失败,提示so is incompatible with armelf_linux_eabi,我在Cmakelists.txt中已经设置so是arm64了

   ```
   set(CMAKE_SYSTEM_PROCESSOR aarch64)
   ```
5. 我想要达到的结果

### 【运行环境】

硬件:
ROM版本:OpenHarmony 4.0.10.18
DevEvoStudio版本:4.0
SDK版本:10
[/md]
作者: 深开鸿_王石    时间: 2024-12-23 14:18
看看这个:https://gitee.com/openharmony/na ... /docs/uselibrary.md

可能几个问题注意下:1,deveco和你运行ohos版本统一,比如,你板子上是4.0,那你的deveco也用4.0,sdk也是api9;就是要配套;2,你这个错误两个问题,一:看看是不是写了dts,不是加了so就好,要写个dts吧你的c方法export的;二:看看hilog,你的so有没有加载,比如libentry.so有没有加载,有没有别的so报错,找不到

作者: youan222    时间: 2024-12-24 14:05
要将@ohos.****.d.ts手动放到C:\Users\xxx(你的用户名)\AppData\Local\OpenHarmony\Sdk\ets\3.1.6.5\api路径下,这样打包的时候才不会报错。
你的方法我也试了,可以参考这两个链接
https://gitee.com/soonliao/dayu- ... 1%E9%83%A8%E5%88%86
https://blog.csdn.net/maniuT/article/details/137689680
作者: kuaile    时间: 2025-1-17 10:18
非运行时问题,从报错看有可能是so加载失败,可以考虑从日志分析




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5