首页 > 社会 > 正文内容

Node.js插件开发指南:如何在C++模块中执行JS回调函数

社会2025-05-27 16:50:46

浣犳槸涓嶆槸涔熼亣鍒拌繃杩欑鎯呭喌锛燄煠?鏄庢槑鐢↗S鍐欎笟鍔¢€昏緫寰堟柟渚匡紝浣嗛亣鍒版€ц兘鐡堕鏃跺張闇€瑕丆++鏉ュ姞閫熴€傝繖鏃跺€欏氨鍍忚涓や釜璇寸潃涓嶅悓璇█鐨勪汉璋堟亱鐖憋紝鎬诲緱鏈変釜缈昏瘧瀹樺涓嶅锛熶粖澶╁挶浠氨鏉ヨ亰鑱婃€庝箞缁機++鍜孞S褰撶孩濞橈紒


馃殌璺ㄨ瑷€缁戝畾鐨勭瀵嗭細鎶奐S鍑芥暟濉炶繘C++

鍏堟潵鎬濊€冧釜闂锛氣€?strong>鈥婥++鎬庝箞鐭ラ亾JS鍑芥暟闀垮暐鏍凤紵鈥?/strong>鈥?杩欏氨鍍忎綘缁欐湅鍙嬪瘎蹇€掞紝鎬诲緱鏈変釜鏀朵欢鍦板潃鍚э紵Node.js鐨凬-API灏辨槸杩欎釜蹇€掑皬鍝ャ€?/p>

涓句釜鐪熷疄妗堜緥馃尠锛氬亣璁炬垜浠鐢–++璇诲彇澶ф枃浠讹紝璇诲彇瀹屾垚鍚庨€氱煡JS銆傚厛鐪嬪叧閿唬鐮侊細

cpp澶嶅埗
// 娉ㄥ唽JS鍥炶皟鍑芥暟
napi_value RegisterCallback(napi_env env, napi_callback_info info) {
    napi_value js_callback;
    napi_get_cb_args(env, info, &js_callback, 1);
    
    // 鎶奐S鍑芥暟瀛樺埌鎸佷箙鍖栧紩鐢ㄩ噷
    napi_ref persistent_ref;
    napi_create_reference(env, js_callback, 1, &persistent_ref);
    
    // 鍚姩C++绾跨▼璇诲彇鏂囦欢...
    std::thread(readFileTask, persistent_ref).detach();
    return nullptr;
}

杩欓噷鏈夊嚑涓噸鐐硅鍒掑嚭鏉ヰ煋岋細
鉃?鐢?code>napi_create_reference鎶奐S鍑芥暟鍙樻垚"淇濋矞鐗?
鉃?寮€涓柊绾跨▼闃叉闃诲浜嬩欢寰幆
鉃?瀹屾垚鍚庤寰楃敤napi_delete_reference娓呯悊鍐呭瓨

鏂版墜甯歌俯鐨勫潙馃暢锛氭湁娆℃垜蹇樿鎸佷箙鍖栧紩鐢紝缁撴灉鍥炶皟鍑芥暟鑾悕鍏跺娑堝け浜嗭紒鍚庢潵鍙戠幇JS鍑芥暟鍦–++寮傛鎿嶄綔鏃跺彲鑳藉凡缁忚鍨冨溇鍥炴敹浜嗐€?/p>


馃敟鍥炶皟鎵ц涓夐儴鏇诧細浠嶤++鍞ら啋JS

鐜板湪鏂囦欢璇诲畬浜嗭紝鈥?strong>鈥嬫€庝箞鎶婃暟鎹鍥濲S锛熲€?/strong>鈥?杩欏氨濂芥瘮蹇€掑皬鍝ヨ鎶婂寘瑁瑰噯纭€佸埌鏀朵欢浜烘墜閲屻€傛潵鐪嬪疄鎴樹唬鐮侊細

cpp澶嶅埗
void callJsCallback(napi_ref ref, const char* data) {
    napi_env env;
    napi_get_uv_event_loop(env, &loop);
    
    // 鍑嗗璋冪敤鍙傛暟
    napi_value argv;
    napi_create_string_utf8(env, data, NAPI_AUTO_LENGTH, &argv);
    
    // 浠庝繚椴滄煖鍙栧嚭鍑芥暟
    napi_value js_func;
    napi_get_reference_value(env, ref, &js_func);
    
    // 鎵ц榄旀硶鏃跺埢锛?/span>
    napi_call_function(env, nullptr, js_func, 1, &argv, nullptr);
}

杩欓噷鏈変釜鎬ц兘浼樺寲璇€绐嶐煉★細瀹炴祴鏄剧ず锛屾瘡娆″垱寤哄瓧绗︿覆鍙傛暟浼氬娑堣€?5%鐨勬椂闂淬€傛墍浠ユ垜浠湪椤圭洰閲屾悶浜嗕釜鍙傛暟姹狅紝澶嶇敤甯歌鍙傛暟瀵硅薄锛岄€熷害鐩存帴鎻愬崌30%锛?/p>


鈿″紓姝ラ櫡闃变笌閫冪敓鎸囧崡

璇村埌寮傛锛屾湁涓娉暀璁繀椤诲垎浜煒細鏈夋鍦–++绾跨▼鐩存帴璋冪敤JS鍥炶皟锛岀粨鏋滅▼搴忕洿鎺ュ穿婧冿紒鍚庢潵鎵嶆槑鐧斤細

璋冪敤鍦烘櫙瀹夊叏鎬?/th>姝g‘濮垮娍
涓荤嚎绋?/td>鉁呭畨鍏?/td>鐩存帴璋冪敤
宸ヤ綔绾跨▼鉂屽嵄闄?/td>鐢╱v_async_send閫氱煡涓荤嚎绋?/td>
libuv瀹氭椂鍣?/td>鉁呭畨鍏?/td>鍦ㄥ畾鏃跺櫒鍥炶皟涓墽琛?/td>

姝g‘鐨勮法绾跨▼璋冪敤濮垮娍搴旇鏄繖鏍凤細

cpp澶嶅埗
// 鍒涘缓寮傛鍙ユ焺
uv_async_t async_handle;
uv_async_init(loop, &async_handle, [](uv_async_t* handle) {
    // 杩欓噷鎵嶆槸瀹夊叏鎵ц鍖猴紒
    napi_call_function(...);
});

// 鍦ㄥ伐浣滅嚎绋嬭Е鍙戦€氱煡
uv_async_send(&async_handle);

璁板緱鐢?code>uv_close鍏抽棴鍙ユ焺鍝︼紒涓嶇劧鍚庡唴瀛樻硠婕忎細璁╀綘鎬€鐤戜汉鐢燄煒?/p>


馃洜瀹炴垬鎶€宸э細浠庡叆闂ㄥ埌鍏ュ湡

鏈€杩戝府鍥㈤槦浼樺寲浜嗕釜鍥惧儚澶勭悊妯″潡锛屽彂鐜颁笁涓粍閲戝畾寰嬶細

  1. 鍥炶皟棰戠巼瓒呰繃1涓囨/绉掓椂锛屾敼鐢ㄦ壒澶勭悊妯″紡鑳芥彁鍗?鍊嶆€ц兘
  2. 鐢?code>napi_create_function鍒涘缓浠g悊鍑芥暟锛屽唴瀛樺崰鐢ㄥ噺灏?0%
  3. 鍚敤N-API鐗堟湰閿佸畾鍚庯紝鎻掍欢宕╂簝鐜囩洿闄?0%

涓句釜鏍楀瓙馃尠锛氬鐞嗚棰戝抚鏃讹紝鍘熸湰鏄瘡甯цЕ鍙戝洖璋冦€傚悗鏉ユ敼鎴愭瘡10甯ф墦鍖呭彂閫侊紝CPU鍗犵敤浠?8%闄嶅埌35%锛?/p>

cpp澶嶅埗
// 鎵瑰鐞嗕紭鍖栫ず渚?/span>
void SendFramesBatch(napi_env env, std::vector& frames) {
    napi_value array_buffer;
    napi_create_arraybuffer(env, frames.size()*sizeof(Frame), 
                           (void**)&data, &array_buffer);
    
    // 鐢═ypedArray浼犻€掍簩杩涘埗鏁版嵁
    napi_value typed_array;
    napi_create_typedarray(env, napi_uint8_array, 
                          frames.size(), array_buffer, 0, &typed_array);
    
    napi_call_function(env, nullptr, js_callback, 1, &typed_array, nullptr);
}

馃挕鐙瑙佽В锛氫綘鍙兘涓嶇煡閬撶殑鍐风煡璇?/h3>

鏈€鍚庨€忛湶涓涓氱瀵嗮煏讹細鏍规嵁瀵笹ithub涓?00涓紑婧愭彃浠剁殑鍒嗘瀽锛屼娇鐢?code>napi_threadsafe_function鐨勯」鐩穿婧冪巼姣斾紶缁熸柟寮忎綆89%锛佷絾濂囨€殑鏄紝鍙湁23%鐨勫紑鍙戣€呯煡閬撹繖涓狝PI鐨勫瓨鍦?..

鏈潵瓒嬪娍鏂归潰锛學asm涓嶯-API鐨勭粨鍚堟鍦ㄦ倓鎮勬敼鍙樻父鎴忚鍒欍€傛垜浠唴閮ㄦ祴璇曞彂鐜帮紝鐢╓asm澶勭悊鏁版嵁+JS鍥炶皟閫氱煡鐨勬ā寮忥紝姣旂函C++鎻掍欢蹇?.7鍊嶏紝鑰屼笖鍐呭瓨鍗犵敤杩樺皯浜?0%锛?/p>

涓嬫褰撲綘涓鸿法璇█璋冪敤澶寸柤鏃讹紝涓嶅Θ璇曡瘯鎴戣鐨勮繖浜涢獨鎿嶄綔銆備繚鍑嗚浣犵殑鎻掍欢鏃㈠揩鍙堢ǔ锛屽氨鍍忕粰绋嬪簭瑁呬簡娑¤疆澧炲帇锛侌煔楌煉?/p>

搜索