通过Emscripten在Javascript中进行结构操作 [英] Struct operations in Javascript through Emscripten

查看:59
本文介绍了通过Emscripten在Javascript中进行结构操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C和Javascript之间互操作脚本时,我遇到了很多问题.

I am having quite a lot of problems with emscripten inter-operating between C and Javascript.

更具体地说,鉴于指向该结构的指针作为

More specifically, I am having trouble accessing a struct created in C in javascript, given that the pointer to the struct is passed into javascript as an external library.

看看下面的代码:

C:

#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>

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 < 32; i++){
        teststr->my_char_array[i] = 120 + i;
    }
    for(int i = 0; i < 32; i++){
        printf("%d\n",teststr->my_char_array[i]);
    }
    read_struct(teststr,sizeof(teststr));
    return 0;
}

JavaScript:

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 进行编译.

这里的问题是,您无法真正在javascript中读取结构,您必须根据struct字段的大小从相应的地址获取内存(因此,从uint32_t读取4个字节,从uint8_t读取1个字节).好的,这不是问题,除非您还必须声明LLVM IR类型以使 getValue 起作用,并且它不包含无符号类型,因此对于数组,它由于变量是无符号的,因此当预期的行为继续上升时,它将达到127并溢出到-128.

The issue here is that you can't really read structs in javascript, you have to get memory from the respective addresses according to the size of the struct field (so read 4 bytes from the uint32_t and 1 byte from the uint8_t). Ok, that wouldn't be an issue, except you also have to state the LLVM IR type for getValue to work, and it doesn't include unsigned types, so in the case of the array, it will get to 127 and overflow to -128, when the intended behaviour is to keep going up, since the variable is unsigned.

我到处都在寻找答案,但是显然这种特定的预期行为并不常见.在我将其应用到的程序中(而不是上面的示例),无法更改结构.

I looked everywhere for an answer but apparently this specific intended behaviour is not common. Changing the struct wouldn't be possible in the program I'm applying this to (not the sample one above).

推荐答案

一种方法是使用Emscripten公开的 HEAP * 类型的数组,这些数组确实具有未签名的视图:

One way is to use the HEAP* typed arrays exposed by Emscripten, which do have unsigned views:

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可以访问它.

This works in my test, running Emscripten 1.29.0-64bit, but as noted it makes assumptions about alignment/padding. The cases I tested seemed to show that a struct seemed to always start on a 4 byte boundary, and that 32 bit unsigned integers inside a struct were also always aligned on a 4 byte boundary, and so accessible by HEAPU32.

但是,我不知道您是否可以依靠Emscripten中的这种行为.据我了解,您无法在通常的C/C ++世界中生活.

However, it's beyond my knowledge to know if you can depend on this behaviour in Emscripten. It's my understanding that you can't in usual C/C++ world.

这篇关于通过Emscripten在Javascript中进行结构操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆