Here is the C code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct TestStruct_s {
int t;
int *tp;
char *s;
};
typedef struct TestStruct_s TestStruct;
struct TestStruct_I_s {
TestStruct * (*cts_V)(void);
TestStruct * (*cts_I)(int t);
TestStruct * (*cts_IP)(int *tp);
TestStruct * (*cts_S)(const char *s);
};
typedef struct TestStruct_I_s TestStruct_I;
TestStruct *cts_V(void) {
TestStruct *ts = malloc(sizeof(TestStruct));
ts->t = 0;
ts->tp = &ts->t;
char *s = NULL;
return ts;
}
TestStruct *cts_I(int t) {
TestStruct *ts = cts_V();
ts->t = t;
return ts;
}
TestStruct *cts_IP(int *tp) {
TestStruct *ts = cts_V();
ts->tp = tp;
return ts;
}
TestStruct *cts_S(const char *s) {
TestStruct *ts = cts_V();
ts->s = (char *)malloc(strlen(s));
strcpy(ts->s, s);
return ts;
}
TestStruct_I *createTestStruct() {
TestStruct_I *tsi = malloc(sizeof(TestStruct_I));
tsi->cts_V = &cts_V;
tsi->cts_I = &cts_I;
tsi->cts_IP = &cts_IP;
tsi->cts_S = &cts_S;
return tsi;
}
void main (int argc, char **argv) {
TestStruct_I *tsi = createTestStruct();
int testIntA = 4;
int testIntB = 42;
TestStruct *ts1 = tsi->cts_V();
TestStruct *ts2 = tsi->cts_I(testIntA);
TestStruct *ts3 = tsi->cts_IP(&testIntB);
TestStruct *ts4 = tsi->cts_S("This is a test");
printf ("O: %s\n", ts4->s);
free(tsi);
free(ts4);
free(ts3);
free(ts2);
free(ts1);
}
And here is the Perl6 part.
use NativeCall;
class TestStruct_s is repr<CStruct> {
has int $!t;
has Pointer[int] $!tp;
has Pointer $!s;
method print_T() {
say $!t;
}
method print_S() {
say $!s;
}
}
class TestStruct_I_s is repr<CStruct> {
has Pointer $!cts_V;
has Pointer $!cts_I;
has Pointer $!cts_IP;
has Pointer $!cts_S;
method cts_V {
$!cts_V();
}
method cts_I(Int $i) {
my &func_sig = nativecast(:(Int --> Pointer[TestStruct_s]), $!cts_I);
return &func_sig($i);
}
method cts_S(Str $s) {
my &func_sig = nativecast(:(str --> Pointer[TestStruct_s]), $!cts_S);
return &func_sig($s);
}
}
sub createTestStruct()
is native('test') returns TestStruct_I_s
{ * };
sub MAIN {
my $tsi = createTestStruct();
my $ts = nativecast(TestStruct_s, $tsi.cts_S("Hello perl6!"));
say $ts.print_S();
say "DONE!";
}
I get the following as output:
# perl6 test.pl
NativeCall::Types::Pointer<0x11>
True
DONE!
So why am I not getting "Hello, perl6!" as output?
So this fixes your teststruct printing issue:
You can also do this: