7

Is there any way to declare an array of objects inside a CStruct?

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

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

A CArray[uint8] would be a char * pointer, not actually reserving space inside the struct.

Instead of My::Struct.new, I could probably make the memory myself (instead of My::Struct.new(), I use a buf8.allocate(xxx) and keep a handle so the GC doesn't reap it, nativecast it to My::Struct), then I have to use pointer math to find the string inside the struct, etc. but it seems like there should be an easier way.

Even if it wasn't fully implemented, a simple way to say "Put 80 bytes here and here's a Pointer to it" would be very nice.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Curt Tilmes
  • 3,035
  • 1
  • 12
  • 24
  • You can still use `CArray[uint8]` to represent your array, but you need to instance it with `my $something = CArray[uint8].new` and then extend it to 80 by doing `$something[80-1] = 0`, which will make the array hold 80 chars. See [here](https://docs.perl6.org/language/nativecall#Arrays) for more about that. – callyalater Feb 06 '18 at 16:47
  • Thanks callyalater, how do I declare that inside the CStruct? – Curt Tilmes Feb 06 '18 at 16:56

2 Answers2

5

Here is my ugly work-around:

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);
    }
}
Curt Tilmes
  • 3,035
  • 1
  • 12
  • 24
0

This was answered here a bit afterwards. It uses the "embedded" has == HAS to declare an array of native elements which is then cast to CArray.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86