龙空技术网

JavaScript/WASM访问C结构体

新缸中之脑 137

前言:

如今兄弟们对“js映射数据表”大体比较重视,同学们都想要剖析一些“js映射数据表”的相关内容。那么小编同时在网络上搜集了一些对于“js映射数据表””的相关文章,希望姐妹们能喜欢,我们快快来了解一下吧!

本文介绍在 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 对象。

原文链接:

标签: #js映射数据表