如何将 char* 参数传递给在 Node.js 中执行的 C 方法?

Posted

技术标签:

【中文标题】如何将 char* 参数传递给在 Node.js 中执行的 C 方法?【英文标题】:How to pass char* argument to a C method executed in Node.js? 【发布时间】:2018-05-06 09:04:43 【问题描述】:

我的C代码如下:

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

我使用 Emscripten 编译器编译的:emcc -s EXPORTED_FUNCTIONS="['_stringlen']" example.c -o example.js

然后,在 Node.js 中,我调用编译后的函数 em_module1._stringlen('sadfsa')。不幸的是,该函数返回4 而不是6(字符串'sadfsa' 的正确长度)。

如何正确地将 Node.js 中的 char* 传递给这个编译函数?

【问题讨论】:

embind & c++ & std::string 比 c & raw 指针更容易。 ***.com/questions/21816960/… 【参考方案1】:

说明

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

快速解决方案

我们将保持 C 代码不变,除了添加缺少的包含:

#include <string.h>

int stringlen(char *p)

   return strlen(p);
;

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

    将我们的字符串转换为原始字节(转换为UInt8Array) 为字符串分配一块模块内存(不需要\0结尾的字符) (A) 访问分配的模块内存块并 (B) 用我们的原始字符串填充它(我们访问内存,因为它代表单个无符号字节 HEAPU8) 释放分配的块
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(Module)

   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'))

【讨论】:

以上是关于如何将 char* 参数传递给在 Node.js 中执行的 C 方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?

将参数传递给 Node.js 异步瀑布

将参数传递给回调 node.js