7

有没有办法在 CStruct 中声明对象数组?

struct my_struct {
    int foo;
    int bar;
    char somestring[80];
};

class My::Struct is repr('CStruct') {
    has int32 $.foo;
    has int32 $.bar;
    ???
}

ACArray[uint8]将是一个char *指针,实际上并不在结构内保留空间。

而不是My::Struct.new,我可能自己制作内存(而不是My::Struct.new(),我使用 abuf8.allocate(xxx)并保留一个句柄,这样 GC 就不会收获它,nativecast它到 My::Struct),然后我必须使用指针数学来找到里面的字符串结构等,但似乎应该有一种更简单的方法。

即使它没有完全实现,一个简单的方式来说“在这里放 80 个字节,这里是一个指向它的指针”会非常好。

4

2 回答 2

5

这是我丑陋的解决方法:

class My::Struct is repr('CStruct') {
    has int32 $.foo is rw;
    has int32 $.bar is rw;
    has int64 $.h0; # 10 int64s = 80 bytes
    has int64 $.h1;
    has int64 $.h2;
    has int64 $.h3;
    has int64 $.h4;
    has int64 $.h5;
    has int64 $.h6;
    has int64 $.h7;
    has int64 $.h8;
    has int64 $.h9;

    method somestring {
        nativecast(Str, Pointer.new(nativecast(Pointer, self)+8))
    }

    sub strcpy(Pointer, Blob, --> Pointer) is native {}

    method set-somestring(Str:D $s) {
        my $buf = "$s\0".encode;
        die "too long" if $buf.bytes > 80;            
        strcpy(Pointer.new(nativecast(Pointer, self)+8), $buf);
    }
}
于 2018-02-06T15:47:06.183 回答
0

稍后在这里回答了这个问题。它使用“嵌入式”有 ==HAS来声明一个原生元素数组,然后将其转换为 CArray。

于 2020-06-14T08:20:31.227 回答