【问题标题】:Declaring an array inside a Perl 6 NativeCall CStruct在 Perl 6 NativeCall CStruct 中声明一个数组
【发布时间】:2018-02-06 15:11:27
【问题描述】:

有没有办法在 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它给我的:: Struct),然后我必须使用指针数学来查找结构内的字符串等,但似​​乎应该有更简单的方法。

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

【问题讨论】:

  • 您仍然可以使用CArray[uint8] 来表示您的数组,但是您需要使用my $something = CArray[uint8].new 对其进行实例化,然后通过执行$something[80-1] = 0 将其扩展到80,这将使数组包含80 个字符.有关详细信息,请参阅here
  • 感谢 clyalater,我如何在 CStruct 中声明它?

标签: arrays struct raku nativecall


【解决方案1】:

这是我丑陋的解决方法:

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);
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多