如何在 React / React Native 中使用编译 JavaScript 的 Emscripten

How to use Emscripten compiled JavaScript within React / React Native

我目前正在使用 Emscripten 将基本 C 函数编译成 JavaScript,以便在 React Native 项目中使用。但是,当我从 React 代码内部导入 Module 时,Module 对象为空。这在 React 和 React Native 项目中都会发生。

运行 index.js 在我的终端中 node ./index.js returns 预期结果。

我正在使用此命令编译 ping.c 并输出 ping.js:

emcc ping.c -o ping.js -s WASM=0 -s EXPORTED_FUNCTIONS='["_pingIt"]'

ping.c:

#include <stdio.h>
#include <emscripten.h>

EMSCRIPTEN_KEEPALIVE
int pingIt() {
  return 1;
}

index.js:

let Module = require('./ping.js');

module.exports = Module;

我正在从 index.js 导出模块并将其导入到我的 React 代码中。

当前行为

// Running in React
console.log(Module); // returns {}

预期行为

// Running in React
console.log(Module._pingIt()); // should return 1

我在 Emscripten 文档 here 中偶然发现了一个 MODULARIZE 设置。我编辑了 emcc 命令:

emcc ping.c -o ping.js -s WASM=0 -s ENVIRONMENT=web -s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap"]' -s MODULARIZE=1

MODULARIZE=1 是魔法位

现在在 index.js 文件中:

let Module = require('./ping.js'); // Your Emscripten JS output file
let pingIt = Module().cwrap('pingIt'); // Call Module as a function

module.exports = pingIt;

现在在 React 组件中,您可以 import pingIt from '<file-location>'; 并像调用任何其他函数一样调用该函数 pingIt()

希望有人觉得这有用!我找不到很多使用 Emscripten 和 React 的例子。

我使用稍微不同的方法从 React Native 调用 ping.c 函数,方法是为模块定义 EXPORT_NAME 并在代码中适当的时候创建模块。

使用 Emscripten emsdk:

emcc ping.c -o ping.js -s WASM=0 -s ENVIRONMENT=web -s MODULARIZE=1 -s "EXPORT_NAME='createPingModule'"

在 React Native 组件中 (App.tsx):

import createPingModule from './ping';

...

createPingModule()
  .then(module => {
    console.log('Module created!');
    let a = module._pingIt();
    console.log(a);
});