有没有更有效的方法将数组从 C++ 返回到 javascript?

2024-01-18

为了将类型化数组从 emscripten'ed C++ 传递到 javascript,我想出了这段代码

#include <emscripten/bind.h>
#include <emscripten/val.h>

auto test(const emscripten::val &input) {
  const auto data = emscripten::convertJSArrayToNumberVector<float>(input); // copies data

  // generate output in some form
  std::vector<float> output = { 1, 2, 3 };
  // make a typed array view of the output
  emscripten::val view{ emscripten::typed_memory_view(output.size(), output.data()) };
  // create new typed array to return
  auto result = emscripten::val::global("Float32Array").new_(output.size());
  // copy data from generated output to return object
  result.call<void>("set", view);

  return result;
}

EMSCRIPTEN_BINDINGS(KissFft) {
  emscripten::function("test", &test);
}

(构建与em++ test.cpp -o test.html --bind)

在这种情况下,有两个额外的副本:

  • 从输入数组到 wasm 内存的复制,据我了解这是不可避免的;
    const auto data = emscripten::convertJSArrayToNumberVector<float>(input);
    
  • 从 wasm 内存到 javascript 对象的复制:
    emscripten::val view{ emscripten::typed_memory_view(output.size(), output.data()) };
    auto result = emscripten::val::global("Float32Array").new_(output.size());
    result.call<void>("set", view);
    
    return result;
    

有没有办法避免在第二种情况下从生成的输出到 javascript 对象的额外复制?

我知道可以像这样返回内存视图:

std::vector<float> output;

auto test(const emscripten::val &input) {
  const auto data = emscripten::convertJSArrayToNumberVector<float>(input);

  //generate output
  return emscripten::val{ emscripten::typed_memory_view(output.size(), output.data()) };
}

EMSCRIPTEN_BINDINGS(KissFft) {
  emscripten::function("test", &test);
}

但在这种情况下,返回的对象指的是拥有的底层内存output静态对象会带来所有后果,例如修改 C++ 端的内存,甚至释放它。


我本来想再低一点。放在这里(而不是注释)来粘贴片段(取自 emscripten 的嵌入示例,这里用 C 语言,但您可以用 C++ 做同样的事情)。

// quick_example.cpp
#include <emscripten/bind.h>
#include <stdio.h>

using namespace emscripten;

struct buffer {
  unsigned int pointer;
  unsigned int size;
};

buffer lerp() {
    buffer myBuffer;
    unsigned int size = 10;

    float * myTab = (float*)malloc(size * sizeof(float));

    for (int i = 0; i < size; i++) {
      myTab[i] = 2.5 * i;
      printf(" Native side index: %d value: %f address: %p\n", i, myTab[i], &myTab[i]);
    }

    myBuffer.pointer = (unsigned int) myTab; 
    myBuffer.size = size;

    printf(" Native side pointer: %p size: %d\n", myTab, size);
    return myBuffer;
}

EMSCRIPTEN_BINDINGS(my_module) {
    value_array<buffer>("buffer")
        .element(&buffer::pointer)
        .element(&buffer::size)
        ;

    function("lerp", &lerp);
}

index.html - 在 js 中,您可以复制、创建视图并最终释放内存(据我所知,这是上面的问题之一?)

   <!doctype html>
    <html>
      <script>
        var Module = {
          onRuntimeInitialized: function() {
            var result =  Module.lerp();
            console.log(" JS side pointer: " + result[0] + " size: " + result[1]);
     
            for (var i = 0; i < result[1]; i++) {
              console.log("index: " + i + " value: " + Module.HEAPF32[(result[0] + i * 4) / 4] + " pointerInc: " + (result[0] + i * 4));
            }
    
            Module._free(result[0]);
          }
        };
      </script>
      <script src="lerp.js"></script>
    </html>

构建命令

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

有没有更有效的方法将数组从 C++ 返回到 javascript? 的相关文章

  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 如何正确取消引用然后删除 JavaScript 对象?

    我想知道从内存中完全取消引用 JavaScript 对象的正确方法 确保删除时不会在内存中悬空 并且垃圾收集器会删除该对象 当我看这个问题时在 JavaScript 中删除对象 https stackoverflow com questio
  • 如何计算特定字符在字符串中出现的次数

    我正在尝试创建一个函数来查看数组中的任何字符是否在字符串中 如果是 有多少个 我尝试计算每一种模式 但是太多了 我尝试使用 Python 中的 in 运算符的替代方案 但效果不佳 function calc fit element var
  • 改变 JavaScript 中的顶部填充

    以下是我在 css 中设置顶部填充的方法 body font size font size px margin 0 padding 100px 0 20px 0 width 100 important 如何使用最简单的 javascript
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 使用 Javascript 设置 cookie [重复]

    这个问题在这里已经有答案了 我正在尝试构建我的第一个移动应用程序 它需要连接到我的 mysql 数据库并使用 json 返回数据 这很好 目前我有一个登录系统 一旦确定用户名和密码存在 它就会返回一条成功消息 对于下一步 我想在我的页面上使
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 如何从浏览器向服务器发送“页面将关闭”消息?

    我想向每个 html 文档添加一个脚本 JavaScript 该脚本向服务器发送两条消息 页面确实打开了 页面将关闭 此消息包含页面打开的时间 打开消息应在文档加载时 或加载完成时 发送 这是简单的部分 The close message
  • 使用javascript动态更新css内容

    需要将 css 更新为动态值 我不确定最好的方法是什么 div style zoom 1 div 缩放级别将根据窗口大小调整触发 应用程序将相应缩放 我将此应用程序加载到 cordova 中并让它在 iPAD 中运行 然后我意识到需要使用
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 滚动顶部不符合预期

    Note 由于上次忘记奖励而重新开放赏金 A Woff 大师已经给出答案 我想在用户展开某一行时到达该行 这样当最后一个可见行展开时 用户不必向下滚动即可查看内容 I used example tbody on click td green
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 没有输入的 jQuery 日期选择器

    我有一个相当复杂的网络应用程序 我想向其中添加一些日期选择 UI 我遇到的问题是我无法从文档中弄清楚如何真正控制日期选择器的出现方式和时间 不涉及任何表单元素 不 我不会添加秘密表单字段 因此简单的开箱即用方法根本行不通 我希望有人可以提供
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 如何在 Android 中切换方向锁定?

    我想在我的首选项活动中创建复选框 允许用户切换方向更改 在类似的问题中 人们只写关于完整方向锁定 通过重写 onConfigurationChanged 方法或在 AndroidManifest xml 中添加 configChanges
  • Team Build Extensions 2010 中的使用 ANT 构建 Java

    我有一个基本的 C 项目 但我想启动 ANT 构建 编译一些非常基本的 java 代码 并触发 junit 测试 如果 junit 测试失败 我如何从 Team Build 2010 基本上是 TFS 2010 中得知 如果是这样 我的 T
  • 如何在 C++ 标头中声明数组?

    这与其他一些问题有关 例如 this https stackoverflow com questions 34987 how to declare an array of strings in c 以及我的其他一些问题 In 这个问题 ht
  • 验证请求源是来自Internet还是Intranet

    我有在互联网上运行的应用程序 其中也包含一些管理模块 我不想让用户在互联网上访问我的管理模块 我希望来自内联网的请求可以访问管理模块 有没有办法在不开发服务管理组件的新应用程序的情况下控制这个问题 如果您使用 servlet 您可以添加过滤
  • 如何使用 Pyrtd/pythoncom 解决“pywintypes.com_error”?

    我正在尝试使用pyrtd https code google com p pyrtd Python模块用于获取可以通过RTD在Excel中获取的信息 但是 当我尝试运行示例 python 脚本 http code google com p
  • Ionic 无限滚动不适用于所有 Android 设备

    我目前正在开发一个离子应用程序并成功实现了无限滚动功能 它在桌面浏览器和较新的 Android 设备上运行良好 但是 我在运行 Android 4 1 或更低版本的手机上遇到问题 问题 我打开页面 它加载并显示前 20 个项目 效果很好 我
  • Firefox 中的 Slidedown 和 SlideUp 循环错误

    http www queness com post 1047 easy to style jquery drop down menu tutorial comment 7912 http www queness com post 1047
  • hibernate - HQL 连接许多子句

    我一直在阅读 Hibernate 文档 但没有找到任何可以解释如何执行以下操作的内容 我尝试将以下 SQL 代码转换为 HQL SELECT msg cmd FROM Schema Messages AS msg LEFT OUTER JO
  • 使用多个 JSON 对象设置单元格的文本

    我有一个简单的网络服务 可以将一些数据传递到表视图中 并且工作正常 这是我目前拥有的代码 cell detailTextLabel setText item objectForKey Ball 1 正如我所说 这完美地工作并显示球号 例如
  • 我可以将 vjslib.dll 放入应用程序的 /bin 目录中吗?

    我正在进行生产部署 不幸的是 我正在部署到一个严格控制的环境 今晚我不太可能获得运行完整 Visual J 可再发行 EXE 的许可 我们的应用程序当前抛出错误 表示找不到程序集 vjslib dll 我可以将其放入应用程序的垃圾箱中 然后
  • QML TableView从特定单元格获取数据(选定行+特定列)

    我有QMLTableView with QSqlQueryModel 我需要选择任何行并从表的每一列中获取数据以分隔TextField 这是 abonentstable h pragma once include
  • 如何从 URL 中删除网页扩展名? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我想从 URL 中删除网页扩展名 有人给了我 htaccess 的代码 但当我打开重写模块时 它在本地主机上工作 但是当我在 Godaddy 上使用它
  • 多方peer.js应用程序

    我对 PeerJs 和 WebRTC 是全新的 我有一个 1 1 NodeJS PeerJS 应用程序在我的远程服务器上运行 效果很好 然而现在我想探索将其扩展到 1 N 模型 其中主机 ID 可以有多个对等点连接到它们 并且每个对等点都可
  • 如果任何源列为 true,则将布尔值聚合为 true

    假设我有下表 id column a column b column c 1 t f t 2 t f f 3 f t f 从上表中 我想 select rows from id 1 2 结果应该是 column a column b col
  • 除了最后一项之外,如何在所有项上设置边框底部

    如果我有一个ul 我如何设置所有的边框底部li除了最后一项之外的项目 我也在尝试使宽度border180 像素 这是我的代码 HTML ul class sideNav li a href history asp History a li
  • 长按注释时,注释图像会被 RedPushPin 替换

    我使用以下内容创建了自定义注释 MKAnnotationView mapView MKMapView mapView viewForAnnotation id
  • 提示用户输入汇编 ci20 seg 错误

    我目前正在 ci20 机器上开发一个小程序 提示用户输入整数值 然后将该值打印到屏幕上 我当前的代码 data prompt asciiz Please enter an integer message asciiz nValue ente
  • 蟒蛇时间偏移

    如何在 python 中应用当前时间的偏移量 换句话说 能够获取当前时间减去 x 小时和 或减去 m 分钟和 或减去 s 秒和 或减去 ms 毫秒 例如 curent time 18 26 00 000 offset 01 10 00 00
  • 单子值的案例

    有没有一种方法可以对 monad 中存储的值执行 case 而无需将名称绑定到它 即 不要这样做 c lt getChar case c of 有没有办法做到这一点 mcase getChar of 或者 如果可以部分应用 case 语句
  • 有没有更有效的方法将数组从 C++ 返回到 javascript?

    为了将类型化数组从 emscripten ed C 传递到 javascript 我想出了这段代码 include