欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript如何調(diào)用C++模塊中的函數(shù)

 更新時(shí)間:2024年01月24日 15:50:06   作者:Hens_Hello_Mr  
這篇文章主要給大家介紹了關(guān)于JavaScript如何調(diào)用C++模塊中函數(shù)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

場(chǎng)景一:JS側(cè)調(diào)用C++側(cè)函數(shù),并傳遞參數(shù)

JS側(cè)調(diào)用C++側(cè)函數(shù)

import testNapi from 'libentry.so'

const TAG = "beixiang";

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Text('調(diào)用testNapi.add')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            const result = testNapi.add(3,4);
            console.log(`${TAG} 調(diào)用testNapi.add的結(jié)果為${result}`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

C++側(cè)方法實(shí)現(xiàn)

static napi_value Add(napi_env env, napi_callback_info info)
{
    // 獲取 2 個(gè)參數(shù),napi_value是對(duì) JS 類型的封裝
    size_t argc = 2;
    napi_value argv[2] = {nullptr};
    
    // 調(diào)用napi_get_cb_info方法,從 info 中讀取傳遞進(jìn)來(lái)的參數(shù)放入argv里
    napi_get_cb_info(env, info, &argc, argv , nullptr, nullptr);

    // 獲取參數(shù)并校驗(yàn)類型
    napi_valuetype valuetype0;
    napi_typeof(env, argv[0], &valuetype0);
    napi_valuetype valuetype1;
    napi_typeof(env, argv[1], &valuetype1);
    
    // 調(diào)用napi_get_value_double把 napi_value 類型轉(zhuǎn)換成 C++ 的 double 類型
    double value0;
    napi_get_value_double(env, argv[0], &value0);
    double value1;
    napi_get_value_double(env, argv[1], &value1);
    
    // 調(diào)用napi_create_double方法把 C++類型轉(zhuǎn)換成 napi_value 類型
    napi_value sum;
    napi_create_double(env, value0 + value1, &sum);
    
    // 返回 napi_value 類型
    return sum;
}
  • napi_get_cb_info (napi_env env, napi_callback_info cbinfo, size_t *argc, napi_value *argv, napi_value *this_arg, void **data)

    • env:調(diào)用 API 的環(huán)境
    • cbinfo:傳遞給回調(diào)函數(shù)的回調(diào)信息
    • argc:指定提供的 argv 數(shù)組的大小并接收參數(shù)的實(shí)際計(jì)數(shù)
    • argv:將表示參數(shù)的 napi_value 復(fù)制到的緩沖區(qū)
    • this_arg:接收調(diào)用的 JavaScript this 參數(shù)
    • data:接收回調(diào)的數(shù)據(jù)指針

    例如Add方法的代碼,napi_get_cb_info(env, info, &argc, argv , nullptr, nullptr);,從 info 中讀取傳遞進(jìn)來(lái)的&argc個(gè)參數(shù)放入argv。

  • napi_get_value_double(napi_env env, napi_value value, double *result)

    把 napi_value 類型轉(zhuǎn)換成 C++ 的 double 類型,供C++側(cè)使用

  • napi_create_double(napi_env env, double value, napi_value *result)

    把 C++ double類型轉(zhuǎn)換成 napi_value 類型,供JS側(cè)使用

  • napi_create_function(napi_env env, const char *utf8name, size_t length, napi_callback cb, void *data, napi_value *result)

不同于以上定義函數(shù),并在Init() 方法內(nèi)聲明 napi_property_descriptor 結(jié)構(gòu)體導(dǎo)出函數(shù)的方式,使用 napi_create_function允許將C++側(cè)函數(shù)創(chuàng)建為可供JS側(cè)調(diào)用的函數(shù)對(duì)象,然后使用napi_set_named_property將創(chuàng)建的函數(shù)對(duì)象導(dǎo)出,以便可以從JS側(cè)訪問(wèn)該函數(shù),如下代碼:

// xxx.cpp    
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
    napi_value fn;
    // 根據(jù)C++側(cè)函數(shù)Add創(chuàng)建函數(shù)fn
    napi_create_function(env, nullptr, 0, Add, nullptr, &fn);
    // 將創(chuàng)建的函數(shù)fn導(dǎo)出,函數(shù)名為newAdd
    napi_set_named_property(env, exports, "newAdd", fn);
    
    napi_property_descriptor desc[] = {
        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr },
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END
// index.d.ts
export const newAdd: (a: number, b: number) => number;

場(chǎng)景二:JS側(cè)不傳參給回調(diào)函數(shù),C++側(cè)接收J(rèn)S側(cè)回調(diào)函數(shù)并執(zhí)行

JS側(cè)調(diào)用C++側(cè)函數(shù)

import testNapi from 'libentry.so'
const TAG = "beixiang";

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Text('調(diào)用無(wú)參回調(diào)函數(shù)')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            // 先注冊(cè)無(wú)參回調(diào)函數(shù)
            testNapi.registerCallback(() => {
              const a = 2;
              const b = 3;
              return a + b;
            })
            // 調(diào)用無(wú)參回調(diào)函數(shù)
            const result = testNapi.handleCallbackWithoutParams();
            console.log(`${TAG} 調(diào)用無(wú)參回調(diào)函數(shù)的結(jié)果為${result}`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

C++側(cè)注冊(cè)回調(diào)函數(shù)

// js函數(shù)回調(diào)
static napi_ref callback = nullptr;
/**
 * 注冊(cè)回調(diào)函數(shù)
 * @param env
 * @param info
 * @return 
 */
static napi_value RegisterCallback(napi_env env, napi_callback_info info) 
{
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    
    napi_create_reference(env, argv[0], 1, &callback);
    
    return nullptr;
}

C++側(cè)執(zhí)行注冊(cè)回調(diào)函數(shù)

/**
 * 執(zhí)行回調(diào)函數(shù),不帶參數(shù)
 * @param env
 * @param info
 * @return 
 */
static napi_value HandleCallbackWithoutParams(napi_env env, napi_callback_info info)
{
    
    napi_value global;
    napi_get_global(env, &global);
    
    napi_value cb = nullptr;
    napi_get_reference_value(env, callback, &cb);

    napi_value result;
    napi_status status = napi_call_function(env, global, cb, 0 , nullptr, &result);

    if (status != napi_ok) return nullptr;
    
    return result;
}
  • napi_create_reference(napi_env env, napi_value value, uint32_t initial_refcount, napi_ref *result)

    此 API 為傳入的對(duì)象創(chuàng)建一個(gè)具有指定引用計(jì)數(shù)的新引用,例如注冊(cè)回調(diào)函數(shù)RegisterCallback中的napi_create_reference(env, argv[0], 1, &callback),將JS側(cè)傳入的對(duì)象argv[0](對(duì)JS來(lái)說(shuō),函數(shù)也是對(duì)象)保存在callback中,供C++側(cè)方法調(diào)用;

  • napi_get_reference_value(napi_env env, napi_ref ref, napi_value *result)

    將創(chuàng)建的引用ref保存到result中

  • napi_call_function(napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv, napi_value *result)

    • env:調(diào)用 API 的環(huán)境
    • recv:this 對(duì)象傳遞給被調(diào)用的函數(shù),一般是當(dāng)前環(huán)境的global對(duì)象,通過(guò)napi_get_global來(lái)獲取。
    • func:表示要調(diào)用的 JavaScript 函數(shù)
    • argc:argv 數(shù)組中元素的計(jì)數(shù)。
    • argv:表示作為參數(shù)傳遞給函數(shù)的 JavaScript 值的 napi_values 數(shù)組
    • result:napi_value 表示返回的 JavaScript 對(duì)象

    在env環(huán)境下,在global對(duì)象中調(diào)用函數(shù)func,該函數(shù)參數(shù)數(shù)組為argv,有argc個(gè)參數(shù),函數(shù)執(zhí)行結(jié)果保存在result。此API允許從C++側(cè)調(diào)用 JavaScript 函數(shù)對(duì)象,例如本文的napi_call_function(env, global, cb, 0 , nullptr, &result);

場(chǎng)景三:JS側(cè)傳參給回調(diào)函數(shù),C++側(cè)接收J(rèn)S側(cè)回調(diào)函數(shù)并執(zhí)行

JS側(cè)調(diào)用C++側(cè)函數(shù)

import testNapi from 'libentry.so'
const TAG = "beixiang";

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Text('調(diào)用有參回調(diào)函數(shù)')
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            // 先注冊(cè)無(wú)參回調(diào)函數(shù)
            testNapi.registerCallback((a: number, b: number) => {
              return a + b;
            })
            // 調(diào)用無(wú)參回調(diào)函數(shù)
            const result = testNapi.handleCallbackWithParams();
            console.log(`${TAG} 調(diào)用有參回調(diào)函數(shù)的結(jié)果為${result}`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

C++側(cè)注冊(cè)回調(diào)函數(shù)

/**
 * 注冊(cè)回調(diào)函數(shù)
 * @param env
 * @param info
 * @return 
 */
static napi_value RegisterCallback(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_create_reference(env, args[0], 1, &callback);
    
    return nullptr;
}

C++側(cè)執(zhí)行注冊(cè)回調(diào)函數(shù)

/**
 * 執(zhí)行回調(diào)函數(shù),帶參數(shù)
 * @param env
 * @param info
 * @return 
 */
static napi_value HandleCallbackWithParams(napi_env env, napi_callback_info info)
{
    napi_value argv[2] = {nullptr};
    
    napi_valuetype valuetype0;
    napi_typeof(env, argv[0], &valuetype0);

    napi_valuetype valuetype1;
    napi_typeof(env, argv[1], &valuetype1);
    
    double value1 = 2;
    double value2 = 3;

    // 創(chuàng)建兩個(gè)double,給callback調(diào)用
    napi_create_double(env, value1, &argv[0]);
    napi_create_double(env, value2, &argv[1]);
    
    
    napi_value global;

    napi_get_global(env, &global);
    
    napi_value cb = nullptr;
    napi_get_reference_value(env, callback, &cb);
    
    napi_valuetype type;
    napi_typeof(env, cb, &type);

    napi_value result;
    // 調(diào)用回調(diào)函數(shù)
    napi_status status = napi_call_function(env, global, cb, 2, argv, &result);
    
    if (status != napi_ok) return nullptr;
    
    return result;
}

值得注意的是,本文JS側(cè)傳遞給C++的回調(diào)函數(shù)是匿名函數(shù),C++側(cè)先將JS回調(diào)函數(shù)先在C++側(cè)注冊(cè),即使用napi_create_reference將JS函數(shù)創(chuàng)建為ref,ref最終會(huì)作為napi_call_function的第三個(gè)參數(shù),可以放心并沒(méi)有在global對(duì)象里面直接去取函數(shù)引用。

另一種實(shí)現(xiàn)方式是JS側(cè)傳遞給C++的回調(diào)函數(shù)是非匿名函數(shù),使用napi_get_named_property在global對(duì)象中直接獲取函數(shù)引用:

JS側(cè)定義非匿名的回調(diào)函數(shù):

function add(a: number, b:number) {
  return a + b;
}

C++側(cè)從global對(duì)象中取出add函數(shù),在napi_call_function引入:

napi_value global, add, arg;
napi_get_global(env, &global);
// 在global對(duì)象中取出名為"add"的對(duì)象/函數(shù)名,保存在add中。
napi_get_named_property(env, global, "add", &add);
...
// 調(diào)用add函數(shù)
napi_call_function(env, global, add, 2 , argv, &result);

總結(jié) 

到此這篇關(guān)于JavaScript如何調(diào)用C++模塊中函數(shù)的文章就介紹到這了,更多相關(guān)JS調(diào)用C++模塊的函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js判斷手機(jī)是否安裝并打開(kāi)app,未安裝則安裝app【兼容Android、ios,親測(cè)可用】

    js判斷手機(jī)是否安裝并打開(kāi)app,未安裝則安裝app【兼容Android、ios,親測(cè)可用】

    這篇文章主要介紹了js判斷手機(jī)是否安裝并打開(kāi)app,未安裝則安裝app,通過(guò)調(diào)用瀏覽器判斷app,兼容Android、ios等系統(tǒng),,需要的朋友可以參考下
    2023-05-05
  • JS制作簡(jiǎn)單的三級(jí)聯(lián)動(dòng)

    JS制作簡(jiǎn)單的三級(jí)聯(lián)動(dòng)

    本文給大家分享的是使用javascript實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的三級(jí)聯(lián)動(dòng)菜單,非常簡(jiǎn)單實(shí)用,有需要的小伙伴過(guò)來(lái)參考下吧。
    2015-03-03
  • JavaScript 常用函數(shù)庫(kù)詳解

    JavaScript 常用函數(shù)庫(kù)詳解

    在WEB開(kāi)發(fā)中,javascript提供了許多函數(shù)供開(kāi)發(fā)人員使用,這些函數(shù)在Ajax流行前足夠了,但要構(gòu)建一個(gè)交互性強(qiáng)些的應(yīng)用恐怕就麻煩了。
    2009-10-10
  • JavaScript中清空數(shù)組的幾種方法

    JavaScript中清空數(shù)組的幾種方法

    本文主要介紹了JavaScript中清空數(shù)組的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 通過(guò)實(shí)例解析js可枚舉屬性與不可枚舉屬性

    通過(guò)實(shí)例解析js可枚舉屬性與不可枚舉屬性

    這篇文章主要介紹了通過(guò)實(shí)例解析js可枚舉屬性與不可枚舉屬性,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 使用requestAnimationFrame實(shí)現(xiàn)js動(dòng)畫(huà)性能好

    使用requestAnimationFrame實(shí)現(xiàn)js動(dòng)畫(huà)性能好

    requestAnimationFrame優(yōu)于setTimeout/setInterval的地方在于它是由瀏覽器專門(mén)為動(dòng)畫(huà)提供的API,在運(yùn)行時(shí)瀏覽器會(huì)自動(dòng)優(yōu)化方法的調(diào)用,并且如果頁(yè)面不是激活狀態(tài)下的話,動(dòng)畫(huà)會(huì)自動(dòng)暫停,有效節(jié)省了CPU開(kāi)銷,這篇文章給大家詳細(xì)介紹使用requestAnimationFrame實(shí)現(xiàn)js動(dòng)畫(huà)
    2015-08-08
  • JS正則表達(dá)式封裝與使用操作示例

    JS正則表達(dá)式封裝與使用操作示例

    這篇文章主要介紹了JS正則表達(dá)式封裝與使用操作,涉及javascript使用正則表達(dá)式針對(duì)郵箱、手機(jī)號(hào)、身份證、用戶名、中文等簡(jiǎn)單驗(yàn)證操作技巧,需要的朋友可以參考下
    2019-05-05
  • 動(dòng)態(tài)添加js事件實(shí)現(xiàn)代碼

    動(dòng)態(tài)添加js事件實(shí)現(xiàn)代碼

    動(dòng)態(tài)添加js事件,主要是不用具體指定位置的事件,這種動(dòng)態(tài)添加事件的方法比較方便,并可以擴(kuò)展等。
    2009-03-03
  • 用js解決數(shù)字不能換行問(wèn)題

    用js解決數(shù)字不能換行問(wèn)題

    當(dāng)一串?dāng)?shù)字的時(shí)候,很多瀏覽器不能自動(dòng)換行,所以可以借助js來(lái)實(shí)現(xiàn)。
    2010-08-08
  • JavaScript中$.ajax()最新用法舉例詳解

    JavaScript中$.ajax()最新用法舉例詳解

    這篇文章主要介紹了JavaScript中$.ajax()最新用法的相關(guān)資料,包括基礎(chǔ)語(yǔ)法、現(xiàn)代回調(diào)方式、異步處理、高級(jí)場(chǎng)景示例、錯(cuò)誤處理、安全注意事項(xiàng)、替代方法以及調(diào)試技巧,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04

最新評(píng)論