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

Posted

技术标签:

【中文标题】如何在 React / React Native 中使用 Emscripten 编译的 JavaScript【英文标题】:How to use Emscripten compiled JavaScript within React / React Native 【发布时间】:2019-01-09 17:51:11 【问题描述】:

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

在我的终端中使用 node ./index.js 运行 index.js 会返回预期结果。

我正在编译 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

【问题讨论】:

我不确定 WASM 是否支持 ES6 导入语法。您是否尝试过在您的index.html 页面中添加script 标记并将Module 作为全局变量访问? @seanulus 我的主要目标是让它在 React Native 项目中运行。我在emcc 命令中使用WASM=0 选项禁用了WASM。 【参考方案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 '&lt;file-location&gt;'; 并像调用其他任何pingIt() 一样调用该函数。

希望有人觉得这很有用!我找不到很多将 Emscripten 与 React 一起使用的示例。

【讨论】:

【参考方案2】:

我使用稍微不同的方法从 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);
);

【讨论】:

以上是关于如何在 React / React Native 中使用 Emscripten 编译的 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

如何在React Native上创建多个屏幕?

如何在 React Native 中使用 React Native Video 显示多个视频? [关闭]

如何在React Native中使用CreateBottomTabNavigator?

无法从“App.js”解析“@react-navigation/native”-React Native + 如何解决?

如何在 React Native 中的循环中查找

如何在 react-native 0.57+ 上为 react-relay(经典)配置 babel