在Perl 6 NativeCall CStruct中声明一个数组

时间:2018-02-06 15:11:28

标签: arrays struct perl6 nativecall

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

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

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

CArray[uint8]是一个char *指针,实际上并没有在结构中保留空间。

而不是My::Struct.new,我本可以自己创建内存(而不是My::Struct.new(),我使用buf8.allocate(xxx)并保留句柄,以便GC无法获取内存, nativecast它到My :: Struct),然后我必须使用指针数学来查找结构中的字符串等,但似​​乎应该有一个更简单的方法。

即使它没有完全实现,也可以用一种简单的方式来说明"在这里放80个字节,这里指向它的指针"会很好。

2 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:0)

稍后here回答了此问题。它使用“嵌入式”的has == HAS声明一个本机元素数组,然后将其强制转换为CArray。