原文链接: https:// medium.com/@tdeniffel/c -to-webassembly-pass-and-arrays-to-c-86e0cb0464f5
by Thomas Deniffel.
译者注:补齐上篇文章中内联的《传递数组给C++...》的翻译,下划线或数字标记的部分是翻译卡壳的地方,可以参看文末的注解或原文。
重要提醒:本文基于我前一篇文章《C ++到WebAssembly指南》。在阅读本文之前,请确保您已大致浏览过那篇文章。
项目结构
首先是一些杂活[1]。下面是我的文件夹结构:
$ tree ..
├── build
├── build.sh
├── cpp
│ ├── CMakeLists.txt
│ ├── sum
│ └── sum.cpp
├── serve.sh
└── web
├── gen
│ ├── sum.js
│ └── sum.wasm
└── index.html
以及下面的相关内容:
$ cat build.shrm build/ -rf
mkdir build
cd build
cmake ../cpp
make
mv sum.js ../web/gen/
mv sum.wasm ../web/gen/
$ cat web/index.html
<html>
<body>
<script src="gen/sum.js"></script>
<script>
Module.onRuntimeInitialized = function() {
// call c++ here
}
</script>
</body>
</html>
从C++传递一个数组到JS
最后是我想从Javascript中调用的C++代码:
$ cat cpp/sum.cpp
extern "C" {
float sum_up(float vals[], int size);
}
float sum_up(float vals[], int size) {
float res = 0;
for(int i=0; i<size; i++)
res += vals[i];
return res;
}
int main() {
float vals[] = {1., 2., 3.};
sum_up(vals, 3);
return 0;
}
注意:在这里如果没有main函数调用sum_up会被编译器优化删除掉。有人知道更好的解决方法吗?
现在进行编译:
$ ./build.sh
这条命令编译文件然后将之拷贝到正确的地方。现在我们可以在JavaScript中调用C++函数了:
$ cat web/index.html
<html>
<body>
<script src="gen/sum.js"></script>
<script>
function transferToHeap(arr) {
const floatArray = toFloatArr(arr);
heapSpace = Module._malloc(floatArray.length *
floatArray.BYTES_PER_ELEMENT); // 1
Module.HEAPF32.set(floatArray, heapSpace >> 2); // 2
return heapSpace;
function toFloatArr(arr) {
const res = new Float32Array(arr.length); // 3
for (let i = 0; i < arr.length; i++)
res[i] = arr[i];
return res;
}
}
function sumUp(arr) {
let arrayOnHeap; // 4.
try {
arrayOnHeap = transferToHeap(arr);
return Module._sum_up(arrayOnHeap, arr.length);
} finally {
Module._free(arrayOnHeap); // 5.
}
}
Module.onRuntimeInitialized = function () {
console.log(
sumUp([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
);
}
</script>
</body>
</html>
以下是代码的一些注释,链接到相关评论(在原文查看):
- 从共享堆(内存)中申请一些空间
- 设置堆上的实际数据
- C ++是类型化的,我们希望明确些
- 在外部定义它,使清理成为可能
- ‘finally’可以在任何情况下都会被调用(包括‘return’和‘error’)。释放已经分配的内存,否则会导致内存泄漏。
现在我们可以:
sumUp([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
看起来很像纯JavaScript,所以我们可以把计算封装在C++中。
接下来的文章:
- 将嵌套数组从C ++传递给JS
- 从JS返回数组给C ++
可以在Twitter了解未来文章的更新:@deniffel
注:
1. housekeeping,家务活,杂活儿,指工作的一部分,但不是主要部分的。