gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 06:07:07 24 4
gpt4 key购买 nike

为了将类型化数组从 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 对象的额外复制?

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

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 中,您可以复制、创建 View 并最终释放内存什么(据我了解,这是上面的问题之一?)

   <!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

关于javascript - 有没有更有效的方法将数组从 C++ 返回到 javascript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65566923/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com