# New Ticket Created by  Jonathan Stowe 
# Please include the string:  [perl #127730]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=127730 >


I found this trying to make a binding for portmidi.

If one has library function that takes an argument of an array of structs that 
has been allocated by the caller and populated by the function like:


#include <stdint.h>
#include <stdio.h>


typedef struct {
   int32_t message;
   int32_t timestamp;   
} Event;

int Pm_Read(Event *buffer, int length) {
   Event event;
   event.message = 16;
   event.timestamp = 8;
   buffer[0] = event;
   return 1;
}


And then attempt to use it in a Perl 6 progran like:
#!perl6

use NativeCall;

class Event is repr('CStruct') {
    has int32 $.message;
    has int32 $.timestamp;
}

sub Pm_Read(CArray[Event] $e, int32 $l) returns int32 is native('./test') { * }

my $a = CArray[Event].new;
$a[0] = Event.new;

Pm_Read($a, 1);

say $a[0];


It will segfault trying to print the populated struct with:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b463b0 in get_int () from 
/home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
Missing separate debuginfos, use: dnf debuginfo-install 
glibc-2.21-13.fc22.x86_64
(gdb) bt full
#0  0x00007ffff7b463b0 in get_int () from 
/home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#1  0x00007ffff7b51f2b in get_attribute () from 
/home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#2  0x00007ffff7af6c02 in MVM_interp_run () from 
/home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#3  0x00007ffff7bae6e9 in MVM_vm_run_file () from 
/home/jonathan/.rakudobrew/moar-nom/install/lib/libmoar.so
No symbol table info available.
#4  0x0000000000400fdf in main ()
No symbol table info available.

(The backtrace is basically the same in the "real" code.)

If the Perl code is altered so that it is passing an array of int64 instead 
then it gets the "right" response:

use NativeCall;

sub Pm_Read(CArray[int64] $e, int32 $l) returns int32 is native('./test') { * }

my $a = CArray[int64].new;
$a[0] = 0;

Pm_Read($a, 1);

say $a[0];
say 16 + (8 +< 32); # the "right" answer

it would seem that the CStruct case is doing something like de-referencing the 
value.

This case doesn't appear to be tested for in the NC tests.




Reply via email to