赞
踩
转载注明出处
这里以cJSON为例,只需要使用到仓库的cJSON.h和cJSON.c
打开DevEco-Studio创建一个native项目
选项随意填写
将cJSON.c和cJSON.h放到项目自动创建的cpp文件夹下
在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具体用法可自行查找资料
选择构建模块‘entry’
编译Hap
在build->outputs->default可找到打包出来的hap
我们解压这个hap
得到3个平台的so动态链接库
也可以直接在build->intermediates->libs->default里找到对应平台的so库不需要解压hap
可在项目的build-profile配置abiFilters,不写默认导出3个平台的so
现在我们就得到了一份看起来不太聪明的so动态链接库
创建一个普通项目
将刚刚生成的3个平台的so库放到libs对应平台的文件夹里,目录没有可手动创建,平台的so不能混用,放对位置。
在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%') } }
不出意外,得到一个undefined
ArkTs加载的so库类似node的napi,不能直接调用c的函数需要我们自己封装一层,用于连接ArkTs和c function 可参考官方文档
按照指引我们返回创建的native项目对cJSON.c进行修改,添加一些函数
打开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的并使用
在新项目中修改代码并运行,得到我们想要的预期结果
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; }
得到预期结果
觉得有用的不忘点个赞,转载注明出处,有任何疑问欢迎在评论区提出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。