Hi David, the first thing that catches my eye is that your struct and the class have the members switched around, so you're already almost guaranteed to read a bogus pointer when trying to get the data.
Also, please note that returning structs directly, or passing structs directly, as arguments is hairy business, you'll probably want to work with pointers instead, which either means your function has to malloc the EncodedData struct, or take a pointer to an already created one as an argument - you would then create the EncodedData on the raku side with a .new Whenever you declare a struct to be passed as argument or received as return value in NativeCall, you will get "TheStruct *" on the C side. Not sure if that's all it takes to fix this. Feel free to write back to the list. Hope to Help - Timo On 08/05/2020 12:44, David Santiago wrote: > Hello, > > I'm porting some personal perl5 scripts to Raku, and one of those > scripts is using Inline::C. > > The inline::c code would contain a function with the signature: > > AV* encode(unsigned char* data, size_t data_size) > > Description of the parameters on the original perl script: > data -> binary string (the value comes from read $FH) > data_size -> size in bytes of binary_string (the value comes from the > return of the read function) > > And it would return an array with two values (a binary string and its crc32): > > """ > SV* enc_string = newSVpv(buffer, 0); > SV* ret = sv_2mortal(newAV()); > av_push(ret, enc_string); > SV* hex_string = newSVpv(hex_number, 0); > av_push(ret, hex_string); > free(hex_number); > return ret; > """ > > > Now for using it in raku, i'm changing the return value to a struct: > typedef struct{ > unsigned char* data; > uint32_t crc32; > } EncodedData; > > So i changed the signature to: > EncodedData encode(unsigned char* data, size_t data_size) > > And i'm returning the struct: > """ > EncodedData ed; > ed.crc32 = crc32; > ed.data = encbuffer; > > return ed; > """ > > Create a shared lib gcc -shared -olibmylib.so mylib.c > > Now on my raku script i did: > """ > class EncodedData is repr('CStruct') { > has uint32 $.crc32; > has str $.data; > } > > sub MAIN() { > sub encode(str $data, size_t $size --> EncodedData) is > native('lib/MyLib/libmylib.so') {*}; > my EncodedData $ed = encode("this is my string that will be > encoded", "this is my string that will be encoded".chars ); > say $ed.crc32.base(16); > say $ed.data; > } > """ > However this isn't working. Everytime i access "$ed.data" I'm getting > the following error: > "fish: 'raku bin/uints.p6' terminated by signal SIGSEGV (Address > boundary error)" > > Why? How do i fix it? > > Also the read method from the IO::Handle returns a Buf. I would like > to pass it directly to my C function. Is there any change in the > C/raku code i should do? > The data field from class EncodedData is type "str". Should it be > CArray[uint8] instead? > > Best regards, > David Santiago