WebAssembly从wasm调用JavaScript方法,即在C ++代码中调用 [英] WebAssembly calling JavaScript methods from wasm i.e. within C++ code

查看:4173
本文介绍了WebAssembly从wasm调用JavaScript方法,即在C ++代码中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩WebAssembly,到目前为止,我能够管理emscripten将我的测试C ++项目编译为wasm文件
em ++为我提供了2个文件,即

I was playing with WebAssembly and so far and I was able to manage emscripten compile my test C++ project to wasm file em++ provides me 2 files i.e.

mainTest.js mainTest.wasm

mainTest.js mainTest.wasm

当我在html页面加载mainTest.js时,我得到一个名为
的JavaScript对象模块

When I load mainTest.js in my html page then I get a JavaScript object called "Module".

我确实找到了如何从javascript调用C ++ / wasm方法,例如:

I did found how to call C++/wasm methods from javascript i.e. something like:

var myTestInteger = Module._callMyTestMethod();

并从
读取字符串 Module.wasmMemory.buffer
,但我不明白如何从C ++代码调用JavaScript。

and read strings from the Module.wasmMemory.buffer , but I do NOT understand how to call JavaScript from C++ code.

ie我希望能够做到这样的事情:

i.e. I would like to be able to do something like that:

#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

和my js方法testExternMethod,我正在另一个名为utils.js的js文件中加载

and the my js method testExternMethod that I am loading in another js file called utils.js

function testExternMethod() {
  console.log("Hello from testExternMethod!" + )
}

这里我想从C ++调用JavaScript testExternJSMethod。

Here I would like to call the JavaScript testExternJSMethod from C++.

当我在Firefox中运行页面时,在调试器控制台中得到-1。

When I run the page in Firefox get "-1" in the debugger console.

那么我在这种情况下缺少什么?不幸的是,Mozilla文档只给出了那些S表达式而不是C ++的例子。

So what I am missing in this case? Unfortunately The Mozilla documentation is giving only examples in those S-expressions instead of C++.

我在示例中缺少什么?在C ++中,我使用extern关键字定义了该方法,即

What am I missing in example? In C++ I have defined the method with the extern keyword i.e.

extern void testExternJSMethod();

但我觉得这不是我所要做的全部。

but I get the feeling that that is not all I have to do.

我相信我应该以某种方式将JavaScript方法以某种方式链接到模块,但我不知道如何。
Module.asm 为我提供 exports 。哪种方法调用应该给我导入?因为我认为这个 _testExternJSMethod()应该在某些导入方法中,我无法弄清楚如何到达它。

I believe that I should somehow link that JavaScript method to the Module somehow but I do not know how. Module.asm gives me the exports. Which method call should give me the imports? since I believe that this _testExternJSMethod() should be in some imports method I can not figure out how to get to it.

推荐答案

我不完全确定你的用例,但是你错过了能够使用你的函数的重要步骤 testExternalJSMethod 。这里有两个选项:

I'm not exactly sure of your use case, but you are missing important steps to be able to use your function testExternalJSMethod. You have two options here:

1 - 用c / c ++定义你的函数。

1 - Define your function in c/c++ .

extern void testExternalJSMethod();

2 - 创建一个名为 myLibrary.js的文件

2 - Create a file called myLibrary.js

3 - 需要使用以下代码将JS函数添加到库文件中的 LibraryManager

3 - The JS function needs to be added to the LibraryManager in your library file with the following code:

function makeAlert(text) {
    alert(text);
}

if (typeof mergeInto !== 'undefined') mergeInto(LibraryManager.library, {
    testExternalJSMethod: function() {
        makeAlert("Hello world");
    }
});

4 - 如果 testExternalJSMethod 取决于外面的任何事情它自己的范围(例如,上面的 makeAlert ),请确保在您的html页面中包含该脚本

4 - If testExternalJSMethod depends on anything outside of its own scope (for example, makeAlert above), make sure to include the script in your html page

<script async type="text/javascript" src="myLibrary.js"></script>

5 - 添加选项 - js-library 到您的emcc命令,并在 myLibrary.js

5 - Add option --js-library to your emcc command, and immediately after the relative path to myLibrary.js

emcc ... --js-library myLibrary.js



选项2 - 传递指针



1 - 用c / c ++定义你的javascript函数类型

Option 2 - Passing Pointers

1 - Define your javascript function type in c/c++

typedef void testExternalJSMethod()

2 - 无论你想在哪里使用这个函数,都要接受一个int参数,是函数指针,并将指针强制转换为函数

2 - Wherever you want this function to be used, accept an int param which will be the function pointer, and cast the pointer to your function

void passFnPointer(int ptr) {
    ((testExternalJSMethod*)ptr)();
}

3 - 使用emscripten的 addFunction()并存储其返回值(指针在c / c ++中)

3 - Use emscripten's addFunction() and store its returned value (the pointer in c/c++)

var fnPtr = Module.addFunction(function () {
    alert("You called testExternalJSMethod");
});

4 - 使用步骤3中存储的指针值传递给我们的函数 passFnPointer

4 - Use the stored pointer value from step 3 to pass to our function passFnPointer

var passFnPointer = Module.cwrap('passFnPointer', 'undefined', ['number']);
passFnPointer(fnPtr);

5 - 添加选项 -s RESERVED_FUNCTION_POINTERS 到你的emcc命令

5 - Add option -s RESERVED_FUNCTION_POINTERS to your emcc command

emcc ... -s RESERVED_FUNCTION_POINTERS=10

这篇关于WebAssembly从wasm调用JavaScript方法,即在C ++代码中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆