nodejs如何将变量传递给c方法char *

问题描述 投票:1回答:1

c代码类似

int stringlen(char* p){
   return strlen(p);
}

使用emcc -s EXPORTED_FUNCTIONS =“ ['_ stringlen']” example.c -o example.js

并且在nodejs中,调用em_module1._stringlen('sadfsa'),为什么返回4 .....如何从nodejs传递c类型的char *?

c node.js emscripten
1个回答
0
投票
说明

带有Web内部功能_stringlen()的已编译WebAssembly模块使用其内存表示为linear memory。编译后的函数仅知道其模块的内存。因此,指针char*必须指向模块的内存块。

快速解决方案

我们将保留完整的C代码,但添加缺少的内容包括:

#include <string.h> int stringlen(char *p) { return strlen(p); };

输出的JavaScript代码example.js包含内存管理等功能。接下来,在test.js脚本中,我们:

    将字符串转换为原始字节(转换为UInt8Array
  1. 为字符串分配模块内存的一部分(结尾不需要\0字符]
  2. ((A)访问模块内存的分配块,并(B)用我们的原始字符串填充它(我们访问内存,因为它代表单个无符号字节HEAPU8
  3. 释放分配的块
  • const Module = require('./example.js'); const str_raw = new TextEncoder().encode('Lorem ipsum'); // 1) let ptr = Module._malloc(str_raw.length); // 2) let chunk = Module.HEAPU8.subarray(ptr, ptr + str_raw.length); // 3A) chunk.set(str_raw); // 3B) console.log(Module._stringlen(chunk.byteOffset)); Module._free(ptr); // 4)
    对于编译,我已强制对WebAssembly模块(-s WASM_ASYNC_COMPILATION=0)进行同步编译,以确保在require()之后该模块将准备就绪。

    emcc -s EXPORTED_FUNCTIONS="['_stringlen']" example.c -o example.js -s WASM_ASYNC_COMPILATION=0

    我们按照node test.js执行脚本。

    其他解决方案

    我最喜欢的解决方案是已经提到的embind。它要求您使用C ++:

    #include <string> #include <emscripten.h> #include <emscripten/bind.h> size_t stringlen(std::string p) { return p.size(); }; EMSCRIPTEN_BINDINGS(Modue) { emscripten::function("stringlen", &stringlen); }

    我们通过使用带有--bind标志的

    embind来编译代码:

    emcc example.cpp -o example.js -s WASM_ASYNC_COMPILATION=0 -std=c++11 --bind
    现在函数调用更加简单:

    const Module = require('./example.js'); console.log(Module.stringlen('Lorem ipsum'))

  • © www.soinside.com 2019 - 2024. All rights reserved.