WebAssembly 从 wasm 调用 JavaScript 方法,即在 C++ 代码中

2024-01-07

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

mainTest.js mainTest.wasm

当我在 html 页面中加载 mainTest.js 时,我会得到一个名为的 JavaScript 对象 ”Module".

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

var myTestInteger = Module._callMyTestMethod();

并从中读取字符串Module.wasm 内存.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 文件中加载的 js 方法 testExternMethod

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

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

当我在 Firefox 中运行该页面时,调试器控制台中会出现“-1”。

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

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

extern void testExternJSMethod();

但我感觉这并不是我要做的全部。

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


我不太确定您的用例,但您缺少使用您的函数的重要步骤testExternalJSMethod。您在这里有两个选择:

选项 1 - 图书馆

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 - If testExternalJSMethod取决于其自身范围之外的任何事物(例如,makeAlert上面),请确保在您的 html 页面中包含该脚本

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

5 - 添加选项--js-library到您的 emcc 命令,并紧接在相对路径之后myLibrary.js

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

选项 2 - 传递指针

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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebAssembly 从 wasm 调用 JavaScript 方法,即在 C++ 代码中 的相关文章

随机推荐

  • 对象函数 (a,b){return new e.fn.init(a,b,h)} 没有方法 'cookie'

    试图获取 a 的值cookie如果它设置并更新div与cookievalue 否则生成一个80 100之间的随机数 将其设置为cookie 然后更新div 我收到错误 Object function a b return new e fn
  • 如何在 html 元素上重写 onkeydown ?

    我继承了一个在弹出窗口中实现禁用 F5 的应用程序 但是 如果用户单击窗口正文下方并按 F5 页面仍会刷新 我将函数调用移至 现在 F5 被禁用 一切都按预期工作 然而 这不是放置代码的最佳位置 如果我可以在我的代码中执行如下所示的操作 我
  • 是什么让 React 库需要 preact-compat?

    我注意到某些图书馆 例如classnames在 Preact 中很容易获得 但其他人喜欢styled components要求preact compat 是什么使得 React 库在 preact 中不受本机支持而需要使用 preact c
  • 函数中返回向量后清除内存

    我有一个函数 可以在其中处理和存储大量数据 然后将结果作为类向量返回 该函数中存储的数据量巨大 我想在该函数完成工作后清除该函数的存储内存 是否有必要这样做 该函数是否自动清除内存 或者我应该通过某些函数清除内存 Update vector
  • 需要将 git 分支重置为原始版本

    我不小心在一个本来不应该在的分支上工作了一段时间 所以我从它的分支上给它起了适当的名字 现在我想将我不应该进入的分支覆盖到原始版本 github 是否有捷径可寻 我尝试删除分支 然后重置跟踪分支 但它只是给了我再次正在处理的版本 如果你还没
  • 根据给定索引和元素数量的列表创建子列表。序言

    我正在尝试解决一个简单的序言问题 但我无法解决它 从列表中 需要创建一个给定索引 I 的子列表 然后从 I 中创建一个给定为 N 的下一个元素 如果索引大于列表长度 我将使子列表为空 如果 N 元素数量 大于列表中的其余元素 我将获得从 I
  • StackExchange API - 反序列化 JSON 响应中的日期

    我正在尝试使用 stackexchange api 我正在尝试获取一些用户信息 如果运行 您将获得 JSON 响应 items badge counts bronze 5630 silver 4212 gold 267 account id
  • 在Python中交换链表中的对,一个链接消失了?

    我一直在学习链表 并且在 python 中实现链表比我预期的要容易 然而 当涉及到解决 交换链表中的对 的问题时 由于某种原因 我的第二个链接在交换过程中消失了 我已经盯着这个问题很多年了 并尝试了在网上找到的不同解决方案 他们都得到相同的
  • 如何在 Swift 中使用闭包从字符串中提取两个整数来执行计算

    我目前正在使用mapSwift 中带有闭包的属性 用于从数组中提取线性因子并计算跨越一个八度音阶的音乐频率列表 let tonic Double 261 626 middle C let factors 1 0 1 125 1 25 1 3
  • 从 icc 获取 Intel 语法 asm 输出,而不是默认的 AT&T 语法?

    我陷入了一个问题 我已经使用 gcc 编译 汇编我的 C 代码一段时间了 并习惯于阅读 Intel 汇编语法 我用的是 masm intel生成程序集文件时的标志 但最近因为公司迁移 他们得到了Intel的icc 声称更好 所以现在我需要使
  • 访问 try-catch 块外部的变量

    我有以下代码 class ClassA public ClassA std string str std string GetSomething int main std string s try ClassA a ClassA s cat
  • 仅使用 css 而不使用 javascript 在悬停时显示叠加层

    当我将鼠标悬停在导航栏菜单上时 我试图制作整页叠加ul 覆盖层div位于页面顶部 当我将鼠标悬停在ul the li链接出现 但覆盖层不出现 我怎样才能使用 CSS 来显示叠加层 有人可以帮忙吗 这是 HTML 和 CSS 代码 标题的完整
  • 如何在 REST Web 服务中发送 JSON 数据?

    如何在 REST Web 服务中发送 JSON 数据 我有一个 json 对象 其中包含产品 Id 商店 Id 价格 产品单位 数量 值 这里除产品单位值外 所有值均为整数 现在 我想将这些值发送到其余的 Web 服务中 能否请您提供一些样
  • Angular2 Safari 后退按钮

    在实际的 Angular2 beta 14 及之前的版本 中 Safari 实际上使用 9 1 上的后退按钮 使用路由和多个视图时 似乎存在问题 https github com angular angular issues 7722 ht
  • 协议对保留计数有影响吗?

    我有一个非常简单的代码 我是故意使用委托创建内存循环 尝试观察和学习如何使用 Xcode 的 Memory Graph 我不明白的是为什么在连接部分 Xcode 说有3连接 应该只有2个 如果我用闭包创建一个内存循环 那么它会显示2连接 我
  • Spring 5 - 无 ServletContext 设置异常

    当我尝试使用 Spring 5 运行我的应用程序时AnnotationConfigApplicationContext类 获取异常No ServletContext set 这是我的主要方法 public class Run public
  • 标识列中存在重复值

    我有一个表 其中有一列名为id这是类型Identity 但此列包含重复值 1 8 然后又包含重复值 1 10 这怎么可能呢 我测试了 Giogri 所说的内容 如果在表有行后启用身份规范 至少在 2008 年 也可能是其他版本 数据库将从最
  • 如何在 Firestore 和 Android 中选择位置?

    我对 Cloud Firestore 非常陌生 所以请帮助我 我正在为青少年创建一个应用程序 我想在其中显示每个城市非常好的地点的列表 我还希望每个用户都可以将任何位置保存到最喜欢的部分 以便他或她可以向他或她的朋友显示该位置列表 我的实际
  • Realm = RLMRealm' 没有成员 'setDefaultRealmPath'

    我已将 Realm framework 和 RealSwift framework 添加到项目中 和 导入领域 虽然我收到此错误 RLMRealm 没有成员 setDefaultRealmPath let directory NSURL N
  • WebAssembly 从 wasm 调用 JavaScript 方法,即在 C++ 代码中

    我正在使用 WebAssembly 到目前为止 我能够管理 emscripten 将我的测试 C 项目编译为 wasm 文件 em 为我提供了 2 个文件 即 mainTest js mainTest wasm 当我在 html 页面中加载