• Lv0
    粉丝0

积分0 / 贡献0

提问2答案被采纳0文章0

如何使用napi加载并调用现有的so库接口

HeavenGo 显示全部楼层 发表于 7 天前

【问题描述】

  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

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

精彩评论2

深开鸿_王石

沙发 发表于 4 天前
看看这个: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

板凳 发表于 3 天前
要将@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

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部