上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

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

guduadmin331月前

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

  • 1 准备一份c代码
  • 2 创建一个native项目
  • 3 编译并导出so库
  • 4 导入第三方so动态库并在ArkTs中使用
  • 5 添加注册函数和其他ArkTs与c function交互的函数 N-Api

    转载注明出处

    1 准备一份c代码

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

    2 创建一个native项目

    打开DevEco-Studio创建一个native项目

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第1张

    选项随意填写

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第2张

    将cJSON.c和cJSON.h放到项目自动创建的cpp文件夹下

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第3张

    在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具体用法可自行查找资料

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第4张

    3 编译并导出so库

    选择构建模块‘entry’

    编译Hap

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第5张

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第6张

    在build->outputs->default可找到打包出来的hap

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第7张

    我们解压这个hap

    得到3个平台的so动态链接库

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第8张

    也可以直接在build->intermediates->libs->default里找到对应平台的so库不需要解压hap

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第9张

    可在项目的build-profile配置abiFilters,不写默认导出3个平台的so

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第10张

    现在我们就得到了一份看起来不太聪明的so动态链接库

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

    创建一个普通项目

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第11张

    将刚刚生成的3个平台的so库放到libs对应平台的文件夹里,目录没有可手动创建,平台的so不能混用,放对位置。

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第12张

    在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%')
      }
    }
    

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第13张

    不出意外,得到一个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的并使用

    在新项目中修改代码并运行,得到我们想要的预期结果

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第14张

    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;
    }
    

    得到预期结果

    编译一份适用于鸿蒙ArkTs的so动态库教学,提供给第三方导入并使用,在这里插入图片描述,第15张

    觉得有用的不忘点个赞,转载注明出处,有任何疑问欢迎在评论区提出。

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦见花蛇是什么预兆  梦见自己牙齿掉光了  梦见大火烧房子很旺