最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

場景一: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è)方法實現(xiàn)

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

    // 獲取參數(shù)并校驗類型
    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ù)
    • 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 中讀取傳遞進來的&argc個參數(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ù)對象,然后使用napi_set_named_property將創(chuàng)建的函數(shù)對象導(dǎo)出,以便可以從JS側(cè)訪問該函數(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;

場景二:JS側(cè)不傳參給回調(diào)函數(shù),C++側(cè)接收JS側(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(() => {
            // 先注冊無參回調(diào)函數(shù)
            testNapi.registerCallback(() => {
              const a = 2;
              const b = 3;
              return a + b;
            })
            // 調(diào)用無參回調(diào)函數(shù)
            const result = testNapi.handleCallbackWithoutParams();
            console.log(`${TAG} 調(diào)用無參回調(diào)函數(shù)的結(jié)果為${result}`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

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

// js函數(shù)回調(diào)
static napi_ref callback = nullptr;
/**
 * 注冊回調(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í)行注冊回調(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 為傳入的對象創(chuàng)建一個具有指定引用計數(shù)的新引用,例如注冊回調(diào)函數(shù)RegisterCallback中的napi_create_reference(env, argv[0], 1, &callback),將JS側(cè)傳入的對象argv[0](對JS來說,函數(shù)也是對象)保存在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 對象傳遞給被調(diào)用的函數(shù),一般是當(dāng)前環(huán)境的global對象,通過napi_get_global來獲取。
    • func:表示要調(diào)用的 JavaScript 函數(shù)
    • argc:argv 數(shù)組中元素的計數(shù)。
    • argv:表示作為參數(shù)傳遞給函數(shù)的 JavaScript 值的 napi_values 數(shù)組
    • result:napi_value 表示返回的 JavaScript 對象

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

場景三:JS側(cè)傳參給回調(diào)函數(shù),C++側(cè)接收JS側(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(() => {
            // 先注冊無參回調(diào)函數(shù)
            testNapi.registerCallback((a: number, b: number) => {
              return a + b;
            })
            // 調(diào)用無參回調(diào)函數(shù)
            const result = testNapi.handleCallbackWithParams();
            console.log(`${TAG} 調(diào)用有參回調(diào)函數(shù)的結(jié)果為${result}`);
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

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

/**
 * 注冊回調(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í)行注冊回調(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)建兩個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è)注冊,即使用napi_create_reference將JS函數(shù)創(chuàng)建為ref,ref最終會作為napi_call_function的第三個參數(shù),可以放心并沒有在global對象里面直接去取函數(shù)引用。

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

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

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

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

napi_value global, add, arg;
napi_get_global(env, &global);
// 在global對象中取出名為"add"的對象/函數(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

荔浦县| 孟津县| 贡山| 兰考县| 岑巩县| 开远市| 北票市| 河东区| 布尔津县| 漳浦县| 瓮安县| 成武县| 安义县| 垣曲县| 石泉县| 武鸣县| 陈巴尔虎旗| 铜山县| 静海县| 常宁市| 崇文区| 驻马店市| 涟水县| 庄浪县| 白朗县| 汝阳县| 红桥区| 泰州市| 云龙县| 缙云县| 墨竹工卡县| 宾阳县| 东乡族自治县| 江口县| 鄂温| 金乡县| 井陉县| 视频| 五原县| 临漳县| 永定县|