NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模
本文介绍在 WASM 中编译 C 库后,如何访问 C 中定义的结构。
当在 Javascript 中使用时,我没有找到任何直接从 WASM 访问结构的方法。 Emscripten 提供了一个选项 embind,它将 C++ 函数和类绑定到 Javascript,但不适用于 C。
我在互联网上搜索了其他开发人员如何解决此类问题,我发现了一些有趣的方法来直接使用 WASM 内存并在 C 和 Javascript 之间映射值。 但是对于 WASM 初学者来说,我发现它有点难以理解。 他们首先要了解 WASM 的内存系统。
我认为首先要鼓励初学者用简单的语言展示它是如何工作的,然后当他对它感到满意或有任何严重的问题或兴趣时,再深入挖掘其中的细节。
为了牢记这一点,我写了这篇文章。 让我们开始吧
首先在C中,定义一个struct,导出相关的函数,包括create、destroy和需要的getter/setter函数:
#include <emscripten.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct _WA_STRUCT {
int a;
double pi;
}WA_STRUCT;
void EMSCRIPTEN_KEEPALIVE structCreate(WA_STRUCT **ppStruct) {
WA_STRUCT *pStruct = malloc(sizeof(WA_STRUCT));
pStruct->a = 35;
pStruct->b = 3.14;
*ppStruct = pStruct;
}
void EMSCRIPTEN_KEEPALIVE structDestory(WA_STRUCT *pStruct) {
free(pStruct);
}
void EMSCRIPTEN_KEEPALIVE structPrint(WA_STRUCT *pStruct) {
printf("Struct Values {%d, %.3f}\n", pStruct->a, pStruct->b);
}
void EMSCRIPTEN_KEEPALIVE structQuery(WA_STRUCT *pStruct, int *pa, double *pb) {
*pa = pStruct->a;
*pb = pStruct->b;
}
void EMSCRIPTEN_KEEPALIVE structSet(WA_STRUCT *pStruct, int a, double b) {
pStruct->a = a;
pStruct->b = b;
}
导出所需C函数的方法有多种。 我使用 EMSCRIPTEN_KEEPALIVE
预处理器导出了函数。 现在只需使用 emscripten 编译器编译这段代码:
emcc test.c -o test.js -s "EXTRA_EXPORTED_RUNTIME_METHODS=['getValue', 'setValue']"
有趣的是如何在 Javascript 中使用导出的函数。 我更愿意将全部责任交给 C 来处理对象及其生命周期,在 Javascript 方面,只是尽量使代码尽可能简单。
这里唯一重要的是要了解 WASM 中没有任何指针概念,一切都在 WASM 堆栈或堆中,因此要获取新创建的结构的地址,首先分配 4 个字节的内存来存储指针,然后获取 所需的信息。 请看下面的代码。 为了在 Javascript 中测试 WASM,我喜欢使用 node.js 环境而不是 web,但这取决于你,你可以使用 web。
const Module = require('./test.js')
Module['onRuntimeInitialized'] = function() {
// create a var containing the address of struct
var ppStruct = Module._malloc(4);
// Create a struct
Module._structCreate(ppStruct);
// Get the actual location of the object
var pStruct = Module.getValue(ppStruct, "i32");
Module._structPrint(pStruct); // print default values
// To query the values from struct, again created two more pointers pa & pb
var pa = Module._malloc(4);
var pb = Module._malloc(4);
Module._structQuery(pStruct, pa, pb); // query values
var a = Module.getValue(pa, "i32"); // ask for 4 byte int value
var b = Module.getValue(pb, "double"); // ask for double
console.log("Queried values {" + a + ", "+ b + "}");
// set new value
Module._structSet(pStruct, 10, 7.25);
Module._structPrint(pStruct);
// Cleanup
Module._structDestory(pStruct);
Module._free(pa);
Module._free(pb);
Module._free(ppStruct);
}
用 Node.js 运行该文件:
node example.js
输出如下:
Struct Values {35, 3.140}
Queried values {35, 3.14}
Struct Values {10, 7.250}
我以非常简单的方式编写代码来解释如何以简单的方式处理 C 结构。 如果你是一位经验丰富的开发人员,当然可以使用自己的方式来绑定 C 结构和 JavaScript 对象。
BimAnt翻译整理,转载请标明出处