编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用

这篇具有很好参考价值的文章主要介绍了编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

转载注明出处

1 准备一份c代码

这里以cJSON为例,只需要使用到仓库的cJSON.h和cJSON.c

2 创建一个native项目

打开DevEco-Studio创建一个native项目
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
选项随意填写
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
将cJSON.c和cJSON.h放到项目自动创建的cpp文件夹下
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
在cmakelists.txt添加两行
add_library(cjson SHARED cJSON.c)
target_link_libraries(cjson PUBLIC libace_napi.z.so)

cjson表示最终导出的so库的名字(libcjson.so)
cJOSN.c表示使用这个文件编译出动态so链接库

项目使用cmake具体用法可自行查找资料
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为

3 编译并导出so库

选择构建模块‘entry’
编译Hap
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为

openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
在build->outputs->default可找到打包出来的hap
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
我们解压这个hap
得到3个平台的so动态链接库
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
也可以直接在build->intermediates->libs->default里找到对应平台的so库不需要解压hap
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为

可在项目的build-profile配置abiFilters,不写默认导出3个平台的so
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
现在我们就得到了一份看起来不太聪明的so动态链接库

4 导入第三方so动态库并在ArkTs中使用

创建一个普通项目
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
将刚刚生成的3个平台的so库放到libs对应平台的文件夹里,目录没有可手动创建,平台的so不能混用,放对位置。
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
在Arkts中使用so库并调用函数

import cjson from 'libcjson.so'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  aboutToAppear() {
    let a= cjson;
    console.log(JSON.stringify(cjson));
    cjson.cJSON_CreateObject();
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为
不出意外,得到一个undefined
ArkTs加载的so库类似node的napi,不能直接调用c的函数需要我们自己封装一层,用于连接ArkTs和c function 可参考官方文档
按照指引我们返回创建的native项目对cJSON.c进行修改,添加一些函数

5 添加注册函数和其他ArkTs与c function交互的函数 N-Api

打开cJSON.c
在文件末尾添加头文件和注册函数

void Fn_cJSON_CreateObject() {
}

#include "napi/native_api.h"

static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"cJSON_CreateObject", NULL, Fn_cJSON_CreateObject, NULL, NULL, NULL, napi_default, NULL}};
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = NULL,
    .nm_register_func = Init,
    .nm_modname = "cjson",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

__attribute__((constructor)) void RegisterEntryModule(void) {
    napi_module_register(&demoModule);
}

desc[]数组每一项都是暴露给ArkTs可以直接调用的函数
你需要在ArkTs中使用到的所有c函数都需要添加进去,用不到的不需要添加
我们暂时暴露cJSON_CreateObject这个函数作为例子
Fn_cJSON_CreateObject名字随意取,cJSON_CreateObject名字是暴露给ArkTs使用的,也是随意取,现在我们修改Fn_cJSON_CreateObject,用于调用c的cJSON_CreateObject函数

napi_value Fn_cJSON_CreateObject(napi_env env, napi_callback_info info) {
    cJSON *cObject = cJSON_CreateObject();

    /*size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {NULL};

    napi_get_cb_info(env, info, &argc, args, NULL, NULL);

    napi_valuetype valuetype0;
    napi_typeof(env, args[0], &valuetype0);

    napi_valuetype valuetype1;
    napi_typeof(env, args[1], &valuetype1);*/

    char *returnStr = "你很棒呀!加油打工人";
    napi_value result;
    napi_create_string_utf8(env, returnStr, strlen(returnStr), &result);

    return result;
}

第一行调用c的cJSON_CreateObject函数
注释部分是用于接收来至ArkTs的参数,我们没传,所以暂时注释掉
这里暂时返回一个 字符串 加油打工人!
重复 第3步和第4步
编译出so库,在新项目中导入替换旧so的并使用
在新项目中修改代码并运行,得到我们想要的预期结果
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为

import cjson from 'libcjson.so'

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  aboutToAppear() {
    let a = cjson;
    const result = cjson.cJSON_CreateObject();
    console.log(result)
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

好了,现在我们已经成功连接ArkTs和c function了,到这已经结束了

cJSON_CreateObject函数返回的是一个cJson的结构体,我们只返回了一个字符串,对应到ArkTs因该为一个Object对象,接着我们继续修改代码,返回c函数结构体真正对应到ArkTs的Object
查看cJSON.h
cJSON的结构体

typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;

转换成ArkTs的数据结构便是

interface cJSON {
  next: cJSON
  prev: cJSON
  child: cJSON
  type: number
  valuestring: string
  valueint: number
  valuedouble: number
  string: string
}

修改Fn_cJSON_CreateObject

napi_value Fn_cJSON_CreateObject(napi_env env, napi_callback_info info) {
    cJSON *cObject = cJSON_CreateObject();

    /*size_t requireArgc = 2;
    size_t argc = 2;
    napi_value args[2] = {NULL};

    napi_get_cb_info(env, info, &argc, args, NULL, NULL);

    napi_valuetype valuetype0;
    napi_typeof(env, args[0], &valuetype0);

    napi_valuetype valuetype1;
    napi_typeof(env, args[1], &valuetype1);*/
    napi_value result;

    char *returnStr = "你很棒呀!加油打工人";
    cObject->valuestring = returnStr;

    napi_create_object(env, &result);

    napi_value type;
    napi_create_int32(env, cObject->type, &type);

    napi_value valueint;
    napi_create_int32(env, cObject->valueint, &valueint);

    napi_value valuestring;
    napi_create_string_utf8(env, cObject->valuestring ? cObject->valuestring : "", strlen(cObject->valuestring), &valuestring);

    napi_value string;
    if (cObject->string) {
        napi_create_string_utf8(env, cObject->string, strlen(cObject->string), &string);
    }

    napi_value valuedouble;
    napi_create_double(env, cObject->valuedouble, &valuedouble);

    napi_value next, prev, child;
    napi_create_reference(env, NULL, 1, &next);
    napi_create_reference(env, NULL, 1, &prev);
    napi_create_reference(env, NULL, 1, &child);

    napi_set_named_property(env, result, "type", type);
    napi_set_named_property(env, result, "valueint", valueint);
    napi_set_named_property(env, result, "valuestring", valuestring);
    napi_set_named_property(env, result, "string", string ? string : NULL);
    napi_set_named_property(env, result, "valuedouble", valuedouble);
    napi_set_named_property(env, result, "next", next);
    napi_set_named_property(env, result, "prev", prev);
    napi_set_named_property(env, result, "child", child);

    return result;
}

得到预期结果
openharmony arkts调用 so 文件,鸿蒙,harmonyos,华为

觉得有用的不忘点个赞,转载注明出处,有任何疑问欢迎在评论区提出。文章来源地址https://www.toymoban.com/news/detail-803871.html

到了这里,关于编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 鸿蒙Native输出so动态库,并提供给第三方导入使用

    DevEco Studio版本:4.0.0.600 API:9 最近在学习鸿蒙的Native输出so动态库,下面就给大家分享下我的学习心得及在实现过程中遇到的问题。 实现需求:通过so库输出文本内容 “你好,鸿蒙!” 参考资料: OpenHarmony Native API 1、创建Native工程 File--New--create Project,选择Native C++项目 正常

    2024年04月10日
    浏览(28)
  • Python程序编译为动态库pyd或so (适用于Windows和Linux)

    Welcome to My Blog 文章唯一地址:https://blog.csdn.net/REAL_liudebai/article/details/125126432 问题:   1)Python源代码扩展名通常为.py,任何人都可以看到源代码内容,能否将Python程序编译为二进制文件( 隐藏我粗暴的编程风格 ,或者你的代码思想,易于调用)。 解决办法:   2)在

    2024年02月01日
    浏览(28)
  • makefile 编译动态链接库使用(.so库文件)

    动态链接库:不会把代码编译到二进制文件中,而是在运行时才去加载, 好处是程序可以和库文件分离,可以分别发版,然后库文件可以被多处共享 动态链接库 动态:动态加载 链接:二进制文件和库文件分离。 库 库文件 .so 新建一个文件TestSo 编译一下 main.cpp 写好之后我们

    2024年01月23日
    浏览(29)
  • aarch64-linux-gcc安装编译及生成so动态库和调用

    官方二进制下载 Ubuntu packages 提供了软件包: gcc-arm-linux-gnueabihf (4:7.4.0-1ubuntu2.3 以及其他的) 。 建议直接从 linaro 的官网下载相应版本的 gcc-linaro 交叉编译工具,并直接选择带有二进制的文件,即在官网入口处选择 binaries 路径,该文件夹下面包含各种版本的已经编译好的 aarch

    2024年02月13日
    浏览(38)
  • Linux gcc/g++编译链接头文件和库(动态库.so 和 静态库.a)

    最近在学习log4cpp库时,使用g++去编译,却发现自己不会链接...,这哪能行,于是网上钻研,终于解决,现在记录下来分享给遇到同样问题的人。 gcc和g++类似,这里就以g++为例! 刚好用到的log4cpp日志库有头文件和动态库.so和静态库.a,这里就以log4cpp库为例。 在安装好log4cpp库

    2024年02月08日
    浏览(38)
  • centos7 arm服务器编译升级安装动态库libstdc++.so.6,解决GLIBC和CXXABI版本低的问题

    前言         由于centos7内置的libstdc++.so.6版本太低,导致安装第三方包的时候,会报“CXXABI_1.3.8”不存在等问题。         自带的打印如下: 如图 升级 注意:当前的libstdc++.so.6.0.25只适用于centos7 arm服务器,其他系统慎用! 1、把libstdc++.so.6.0.25拷贝到/usr/lib64目录下 2、备份

    2024年01月18日
    浏览(37)
  • 第一个ArkTS项目实践-鸿蒙ArkTS

    本篇文章是官网上视频对ArkTS开发实践的第一个视频,主要是引导大家对ArkTS的一个了解。 开发文档官网 ArkTS通过struct声明组件名,并通过@Component和@Entry装饰器,来构成一个自定义组件。 使用@Entry和@Component装饰的自定义组件作为页面的入口,会在页面加载时首先进行渲染。

    2024年02月12日
    浏览(25)
  • 鸿蒙实战:ArkTs 开发一个鸿蒙应用

    学习过的 ArkTs 知识点,一步一步开发一个小的鸿蒙应用示例,涉及到  ArkTs 语法、注解 @Entry 、 @Component 、 @state 、路由、生命周期、 @Prop 、 @Link 、常用组件的使用等等知识点。 要开发一个鸿蒙应用,首先我们需要知道 系统是如何找到页面的启动入口 。 鸿蒙如何启动应用

    2024年02月22日
    浏览(36)
  • Android Studio 进行NDK开发,实现JNI,以及编写C++与Java交互(Java调用本地函数)并编译出本地so动态库

    1.首先认识一下NDK。 (1)什么是NDK? NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C/C++的动态库,并能自动将so和java应用一起打包成apk。NDK集成了交叉编译器(交叉编译器需要UNIX或LINUX系统环境),并提供了相应的mk文件隔离CPU、平台、ABI等差异,

    2024年02月11日
    浏览(30)
  • 鸿蒙tabbar ArkTS

    做了仿照现在应用的做了一个tabbar。 官方文档地址 参考文档 其中有个比较重要的点是,对image资源的引用问题。 资源相关说明 图片是resources目录下的base目录下的。 media目录下的图片的资源不能添加文件夹,只能是文件,而且文件的命名规则是只能包含字母大小写和下划线

    2024年02月08日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包