开发某个小工具,需要在JavaScript(没错,为了使用element来写图形界面)中使用第三方SDK,该SDK中涉及到了C++多线程回调。学习了一下Node-API,成果如下:
为了让js那边传过来的函数可以在其他线程进行调用,首先需要把取到的函数转换为线程安全的
napi_get_cb_info(env,cbinfo,&argc,&js_cb,nullptr,nullptr); //获取js那边传来的回调 napi_create_threadsafe_function(env,js_cb,nullptr,cb_name,0,1,nullptr,nullptr,nullptr,&test,&func); //将其转化为线程安全的,关于test,和func参数的定义见下面区
全局定义线程安全函数变量,和它的回调函数
napi_threadsafe_function func; void test(napi_env env, napi_value js_callback, void* context, void* data){ napi_value name,undef,obj,val; napi_create_object(env,&obj); napi_create_string_utf8(env, "val", NAPI_AUTO_LENGTH, &val); napi_create_string_utf8(env, (char*)data, NAPI_AUTO_LENGTH, &name); napi_set_property(env,obj,val,name); napi_get_undefined(env,&undef); napi_call_function(env, undef, js_callback, 1,&obj, nullptr); delete[] data; //在这里删除了动态申请的data指向的空间 }
然后就可以在任何函数里调用我们的func回调了,完整代码如下,以供参考
#include <node_api.h> #include <iostream> #include <thread> #include <string.h> napi_threadsafe_function func; void mycb(char *str){ char *ip=new char[10]; strcpy(ip,str); napi_call_threadsafe_function(func,ip,napi_tsfn_blocking); } void test(napi_env env, napi_value js_callback, void* context, void* data){ napi_value name,undef,obj,val; napi_create_object(env,&obj); napi_create_string_utf8(env, "val", NAPI_AUTO_LENGTH, &val); napi_create_string_utf8(env, (char*)data, NAPI_AUTO_LENGTH, &name); napi_set_property(env,obj,val,name); napi_get_undefined(env,&undef); napi_call_function(env, undef, js_callback, 1,&obj, nullptr); delete[] data; } void test2(void(*mycb)(char *str),char* p){ mycb(p); } napi_value Method(napi_env env, napi_callback_info cbinfo) { napi_status status; size_t argc = 1; napi_value js_cb,global; napi_value cb_name; napi_create_string_utf8(env, "realpCb", NAPI_AUTO_LENGTH, &cb_name); napi_get_cb_info(env,cbinfo,&argc,&js_cb,nullptr,nullptr); napi_create_threadsafe_function(env,js_cb,nullptr,cb_name,0,1,nullptr,nullptr,nullptr,&test,&func); char a[]="123"; char b[]="456"; char c[]="789"; std::thread pp(test2,mycb,a); std::thread pp1(test2,mycb,b); std::thread pp2(test2,mycb,c); pp.join(); pp1.join(); pp2.join(); napi_release_threadsafe_function(func,napi_tsfn_release); return cb_name; } napi_value init(napi_env env, napi_value exports) { napi_status status; napi_value fn; status = napi_create_function(env, nullptr, 0, Method, nullptr, &fn); if (status != napi_ok) return nullptr; status = napi_set_named_property(env, exports, "hello", fn); if (status != napi_ok) return nullptr; return exports; } NAPI_MODULE(NODE_GYP_MODULE_NAME, init)
实现了一个hello函数,该函数会执行三个子线程调用js端传来的回调,并将结果以Object的形式返回到JS端
var main=require("./main.node") main.hello((res)=>{ console.log(res) }) process.on("exit",()=>{ console.log("close"); })
Electron写界面和读Excel是真的香阿,方便写批量操作小工具哦
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号