我正在玩WebAssembly,到目前为止,我能够管理emscripten将我的测试C ++项目编译为wasm文件em ++为我提供了2个文件,即
mainTest.js mainTest.wasm
当我在我的html页面中加载mainTest.js时,我得到一个名为“Module”的JavaScript对象。
我确实找到了如何从javascript调用C ++ / wasm方法,例如:
var myTestInteger = Module._callMyTestMethod();
并从Module.wasmMemory.buffer读取字符串,但我不明白如何从C ++代码调用JavaScript。
即我希望能够做到这样的事情:
#ifdef __cplusplus
extern "C" {
#endif
extern void testExternJSMethod();
int main()
{
cout << " Hello From my Test1 !" << endl;
testExternJSMethod();
return 0;
}
int EMSCRIPTEN_KEEPALIVE callMyTestMethod(){
return 26;
}
#ifdef __cplusplus
}
#endif
以及我在另一个名为utils.js的js文件中加载的my js方法testExternMethod
function testExternMethod() {
console.log("Hello from testExternMethod!" + )
}
在这里,我想从C ++中调用JavaScript testExternJSMethod。
当我在Firefox中运行页面时,在调试器控制台中获取“-1”。
那么我在这种情况下缺少什么?不幸的是,Mozilla文档仅提供了那些S表达式而不是C ++的示例。
我在例子中缺少什么?在C ++中,我用extern关键字定义了方法,即
extern void testExternJSMethod();
但我觉得这不是我必须做的全部。
我相信我应该以某种方式将JavaScript方法链接到模块,但我不知道如何。 Module.asm给了我出口。哪种方法调用应该给我进口?因为我相信这个_testExternJSMethod()
应该采用一些进口方法,我无法弄清楚如何达到它。
我不完全确定你的用例,但你错过了能够使用你的功能testExternalJSMethod
的重要步骤。你有两个选择:
1 - 用c / c ++定义你的函数。
extern void testExternalJSMethod();
2 - 创建一个名为myLibrary.js
的文件
3 - 需要使用以下代码将JS函数添加到库文件中的LibraryManager
:
function makeAlert(text) {
alert(text);
}
if (typeof mergeInto !== 'undefined') mergeInto(LibraryManager.library, {
testExternalJSMethod: function() {
makeAlert("Hello world");
}
});
4 - 如果testExternalJSMethod
依赖于其自身范围之外的任何东西(例如,上面的makeAlert
),请确保在您的html页面中包含该脚本
<script async type="text/javascript" src="myLibrary.js"></script>
5 - 在emcc命令中添加选项--js-library
,并在myLibrary.js
的相对路径后立即添加
emcc ... --js-library myLibrary.js
1 - 用c / c ++定义你的javascript函数类型
typedef void testExternalJSMethod()
2 - 无论你想在哪里使用这个函数,接受一个int参数,它将是函数指针,并将指针强制转换为你的函数
void passFnPointer(int ptr) {
((testExternalJSMethod*)ptr)();
}
3 - 使用emscripten的addFunction()
并存储其返回值(指针在c / c ++中)
var fnPtr = Module.addFunction(function () {
alert("You called testExternalJSMethod");
});
4 - 使用步骤3中存储的指针值传递给我们的函数passFnPointer
var passFnPointer = Module.cwrap('passFnPointer', 'undefined', ['number']);
passFnPointer(fnPtr);
5 - 将选项-s RESERVED_FUNCTION_POINTERS
添加到emcc命令
emcc ... -s RESERVED_FUNCTION_POINTERS=10
您是否尝试过查看Emscripten文档?它有关于interacting with code的整个部分,详细介绍了如何将C / C ++函数公开给JavaScript并从C / C ++调用JavaScript函数。
Emscripten提供了两种从C / C ++调用JavaScript的主要方法:使用emscripten_run_script()运行脚本或编写“内联JavaScript”。
值得注意的是,Mozilla文档详细介绍了纯WebAssembly,而Emscripten则围绕WebAssembly添加了更多的框架和工具,以便更容易移植大型C / C ++代码库。