HarmonyOS 鸿蒙Next:如何在c++中使用ARKts为C++提供的回调函数

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:如何在c++中使用ARKts为C++提供的回调函数

假如目前我的c++接口函数需要提供给artks层调用

需要一个回调函数作为参数异步调用,假设回调声明如下

typedef int(__stdcall *callback)(const void *message,int size);

那么我的napi胶水层该如何继续修改

int _callback(const void *message, int size){
}

napi_value napi_start(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    napi_ref callback_ref;
    napi_create_reference(env, args[0], 1, &callback_ref); 
    int rv = start(callback_ref ? _callback : NULL);
    napi_value result;
    napi_create_int32(env, rv, &result);
    return result;
}
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"start", NULL, napi_start, 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 = "entry",
    .nm_priv = ((void*)0),
    .reserved = {0},
};

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

更多关于HarmonyOS 鸿蒙Next:如何在c++中使用ARKts为C++提供的回调函数的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

9 回复

开发者您好,该问题已反馈至相关人员,请耐心等待。

更多关于HarmonyOS 鸿蒙Next:如何在c++中使用ARKts为C++提供的回调函数的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


你好,我也遇到了使用C++回调函数的问题,请问具体是如何解决的,

创建线程安全函数

  • 线程安全函数是指在多线程环境中能够正确处理数据共享和修改的函数。
  • 要实现线程安全,可以使用互斥锁(mutex)来保护共享资源。
  • 示例代码:
import threading

class Counter:
    def __init__(self):
        self.count = 0
        self.lock = threading.Lock()

    def increment(self):
        with self.lock:
            self.count += 1

这个示例中,Counter类有一个计数器count和一个互斥锁lockincrement方法使用with self.lock:语句确保在同一时间只有一个线程可以执行self.count += 1操作。

姓名

张三

联系方式

邮箱: zhangsan@example.com
电话: 123-456-7890

教育背景

本科
计算机科学与技术
北京大学
2010 - 2014

工作经验

软件工程师
ABC科技有限公司
2014 - 至今

项目经验

项目1
描述: 参与开发公司核心产品,负责模块设计与编码。
责任: 模块设计,编码实现,代码审查。

项目2
描述: 领导团队完成新产品的研发工作。
责任: 需求分析,项目管理,团队协作。

可以看下这个帖子,ARKts调用c++异步回调。NAPI 异步回调使用callback方式示例:

https://developer.huawei.com/consumer/cn/forum/topic/0203148316948681384?fid=0101591351254000314

感谢,其实我回复里那个写法是类似你发的这个的,只是这个回调我会传递给start,但是不一定在start里进行回调可能会在其他函数阶段回调,但是只要 _callbakc 里存在 napi_call_function 就会发生我图里那个 crash,奔溃,

我使用了const void *userdata的形式去使用以下修改后的函数声明:

int start(callback fun,const void *userdata);

修改后的回调:

typedef int(__stdcall *callback)(const void *userdata,const void *message,int size);

以下是胶水层:

typedef struct {  
    napi_env env;  
    napi_ref callback_ref;  
} OhosCallbackWrapper;
static int _callback(const void *usrdata, const void *message, int size){
    OhosCallbackWrapper *wrapper = (OhosCallbackWrapper *)usrdata;
    napi_status status;
    
    napi_value m_callback;
    status = napi_get_reference_value(wrapper->env, wrapper->callback_ref, &m_callback);  
    if (status != napi_ok) {
        napi_throw_error(wrapper->env, NULL, "Failed to get function");
        return -1;
    }  

    napi_value message_val, size_val;
    status = napi_create_int32(wrapper->env, size, &size_val);
    status = napi_create_string_utf8(wrapper->env, static_cast<const char*>(message), size, &message_val);
    
    const size_t argc = 2;  
    napi_value args[argc] = {message_val, size_val};
    napi_value callback_result;
    napi_call_function(wrapper->env, nullptr, m_callback, argc, args, &callback_result);
    int int_result;  
    napi_get_value_int32(wrapper->env, callback_result, &int_result);
    return int_result;
}
static napi_value napi_start(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
   
    napi_ref callback_ref;  
    napi_create_reference(env, args[0], 1, &callback_ref);

    OhosCallbackWrapper *wrapper = (OhosCallbackWrapper *)malloc(sizeof(OhosCallbackWrapper));
    wrapper->env = env;
    wrapper->callback_ref = callback_ref;
    
    int rv = start(_callback, wrapper);
    
    napi_value result;
    napi_create_int32(env, rv, &result);
    return result;
}

artks层是:

import testNapi from 'libentry.so'
function myCallback(message: string, size: number) {
  console.log("Callback:message=", message, ", size=", size);
  return 0;
}
let e = testNapi.start(myCallback);

但是这样的方法在start时会发生crash。注销掉napi_call_function就不会crash。

在HarmonyOS(鸿蒙)Next中,ARKts(Ark UI TypeScript)框架虽然主要基于TypeScript开发,但它也提供了一些机制来与其他编程语言(如C++)进行互操作。要在C++中使用ARKts为C++提供的回调函数,你通常需要通过JNI(Java Native Interface,虽然这里不涉及Java代码,但概念类似)或者特定的鸿蒙API来实现跨语言调用。

具体步骤如下:

  1. 定义回调接口:在ARKts中定义一个JavaScript接口,该接口将用于调用C++中的函数。这通常通过导出特定的函数或对象到全局命名空间来完成。

  2. 生成头文件:使用鸿蒙提供的工具将ARKts中的接口转换成C++可以识别的头文件。这个头文件将包含用于回调的C++函数签名。

  3. 实现回调:在C++代码中实现这些回调函数。确保这些函数的签名与头文件中的定义相匹配。

  4. 注册回调:在ARKts代码中,通过适当的机制(可能是鸿蒙提供的API)将这些C++函数注册为回调。

  5. 调用回调:在ARKts代码中,当特定事件发生时,调用注册的C++回调函数。

请注意,由于鸿蒙系统的不断更新和API的变更,具体的实现细节可能会有所不同。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部