Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active April 4, 2016 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xliff/b3e0dfd7ab712aee7ef59975decd42d8 to your computer and use it in GitHub Desktop.
Save Xliff/b3e0dfd7ab712aee7ef59975decd42d8 to your computer and use it in GitHub Desktop.
So why doesn't this bit of NativeCall work?

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?

@Timbus
Copy link

Timbus commented Apr 4, 2016

So this fixes your teststruct printing issue:

class TestStruct_s is repr<CStruct> {
        has int          $!t;
        has Pointer[int] $!tp;
        has Str          $!s;

        method print_T() {
                say $!t;
        }

        method print_S() {
                say $!s;
        }
}

You can also do this:

class TestStruct_s is repr<CStruct> {
        has int          $!t;
        has Pointer[int] $!tp;
        has Pointer[Str] $!s;

        method print_T() {
                say $!t;
        }

        method print_S() {
                say $!s.deref;
        }
}

@Xliff
Copy link
Author

Xliff commented Apr 4, 2016

Thanks so much, TIMBuS! I will update the gist with the full solution, later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment