通过Emscripten在Javascript中进行结构化操作

我在使用C和Javascript之间的emscripten互操作方面遇到了很多问题。

更具体地说,我无法访问在javascript中使用C创建的结构,因为指向结构的指针作为外部库传递给javascript。

看一下下面的代码:

C:

#include  #include  #include  struct test_st; extern void read_struct(struct test_st *mys, int siz); struct test_st{ uint32_t my_number; uint8_t my_char_array[32]; }; int main(){ struct test_st *teststr = malloc(sizeof(struct test_st)); teststr->my_number = 500; for(int i = 0; i my_char_array[i] = 120 + i; } for(int i = 0; i my_char_array[i]); } read_struct(teststr,sizeof(teststr)); return 0; } 

使用Javascript:

 mergeInto(LibraryManager.library, { read_struct: function(mys,siz){ var read_ptr = 0; console.log("my_number: " + getValue(mys + read_ptr, 'i32')); read_ptr += 4; for(var i = 0; i < 32; i++){ console.log("my_char[" + i + "]: " + getValue(mys + read_ptr, 'i8')); read_ptr += 1; }; }, }); 

然后使用emcc cfile.c --js-library jsfile.js编译emcc cfile.c --js-library jsfile.js

这里的问题是你无法真正读取javascript中的结构,你必须根据struct字段的大小从各自的地址获取内存(因此从uint32_t读取4个字节,从uint8_t读取1个字节)。 好吧,这不会是一个问题,除了你还必须说明LLVM IR类型让getValue工作,并且它不包括无符号类型,所以在数组的情况下,它将达到127并溢出到-128,当预期的行为是继续上升时,因为该变量是无符号的。

我到处寻找答案,但显然这种特定的预期行为并不常见。 在我正在应用它的程序中不能改变结构(不是上面的样本)。

一种方法是使用Emscripten公开的HEAP*类型数组,它具有无符号视图:

 mergeInto(LibraryManager.library, { read_struct: function(myStructPointer, size) { // Assumes the struct starts on a 4-byte boundary var myNumber = HEAPU32[myStructPointer/4]; console.log(myNumber); // Assumes my_char_array is immediately after my_number with no padding var myCharArray = HEAPU8.subarray(myStructPointer+4, myStructPointer+4+32); console.log(myCharArray); } }); 

这适用于我的测试,运行Emscripten 1.29.0-64bit,但如上所述,它对对齐/填充做出了假设。 我测试的情况似乎表明结构似乎总是从4字节边界开始,并且结构内部的32位无符号整数也总是在4字节边界上对齐,因此可由HEAPU32访问。

但是,我不知道你是否可以在Emscripten中依赖这种行为。 这是我的理解,你不能在通常的C / C ++世界。