Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active February 21, 2019 23:29
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/13aff4976b12923f62e0a70dad62bea6 to your computer and use it in GitHub Desktop.
Save Xliff/13aff4976b12923f62e0a70dad62bea6 to your computer and use it in GitHub Desktop.
use v6;

use lib <lib t/04-nativecall>;
use CompileTestLib;
use NativeCall;
use Test;

plan 22;

compile_test_lib('15-rw-args');

sub SetChar(int8 is rw)            is native('./15-rw-args') { * }
sub PassChar(int8 is rw)           returns int8 is native('./15-rw-args') { * }
sub SetShort(int16 is rw)          is native('./15-rw-args') { * }
sub PassShort(int16 is rw)         returns int16 is native('./15-rw-args') { * }
sub SetLong(long is rw)            is native('./15-rw-args') { * }
sub PassLong(long is rw)           returns long is native('./15-rw-args') { * }
sub SetLongLong(longlong is rw)    is native('./15-rw-args') { * }
sub PassLongLong(longlong is rw)   returns longlong is native('./15-rw-args') { * }
sub SetFloat(num32 is rw)          is native('./15-rw-args') { * }
sub PassFloat(num32 is rw)         returns num32 is native('./15-rw-args') { * }
sub SetDouble(num64 is rw)         is native('./15-rw-args') { * }
sub PassDouble(num64 is rw)        returns num64 is native('./15-rw-args') { * }
sub SetUChar(uint8 is rw)          is native('./15-rw-args') { * }
sub PassUChar(uint8 is rw)         returns uint8 is native('./15-rw-args') { * }
sub SetUShort(uint16 is rw)        is native('./15-rw-args') { * }
sub PassUShort(uint16 is rw)       returns uint16 is native('./15-rw-args') { * }
sub SetULong(ulong is rw)          is native('./15-rw-args') { * }
sub PassULong(ulong is rw)         returns ulong is native('./15-rw-args') { * }
sub SetULongLong(ulonglong is rw)  is native('./15-rw-args') { * }
sub PassULongLong(ulonglong is rw) returns ulonglong is native('./15-rw-args') { * }
sub SetPtrToPtr(Pointer is rw) returns int32 is native('./15-rw-args') { * }

sub ReturnPointerToArray(CArray[CArray[uint8]] is rw) returns long is native('./15-rw-args') { * }
sub VerifyBufferChanged() returns int64 is native('./15-rw-args') { * }

my int8 $c; SetChar($c);
is $c, 97, 'Perl\'s rw variable was set by C (char)';
is PassChar($c), 97, 'Perl\'s rw variable was passed and returned by C (char)';

my int16 $s; SetShort($s);
is $s, 387, 'Perl\'s rw variable was set by C (short)';
is PassShort($s), 387, 'Perl\'s rw variable was passed and returned by C (short)';

my long $l; SetLong($l);
is $l, 777, 'Perl\'s rw variable was set by C (long)';
is PassLong($l), 777, 'Perl\'s rw variable was passed and returned by C (long)';

my longlong $ll; SetLongLong($ll);
is $ll, 15324, 'Perl\'s rw variable was set by C (long long)';
is PassLongLong($ll), 15324, 'Perl\'s rw variable was passed and returned by C (longlong)';

my num32 $f; SetFloat($f);
is-approx $f, 6.66, 'Perl\'s rw variable was set by C (float)';
is-approx PassFloat($f), 6.66, 'Perl\'s rw variable was passed and returned by C (float)';

my num64 $d; SetDouble($d);
is-approx $d, 12.12, 'Perl\'s rw variable was set by C (double)';
is PassDouble($d), 12.12, 'Perl\'s rw variable was passed and returned by C (double)';

my uint8 $uc; SetUChar($uc);
is $uc, 153, 'Perl\'s rw variable was set by C (unsigned char)';
is PassUChar($uc), 153, 'Perl\'s rw variable was passed and returned by C (unsigned char)';

my uint16 $us; SetUShort($us);
is $us, 387, 'Perl\'s rw variable was set by C (unsigned short)';
is PassUShort($us), 387, 'Perl\'s rw variable was passed and returned by C (unsigned short)';

my ulong $ul; SetULong($ul);
is $ul, 777, 'Perl\'s rw variable was set by C (unsigned long)';
is PassULong($ul), 777, 'Perl\'s rw variable was passed and returned by C (unsigned long)';

my ulonglong $ull; SetULongLong($ull);
is $ull, 15324, 'Perl\'s rw variable was set by C (unsigned long long)';
is PassULongLong($ull), 15324, 'Perl\'s rw variable was passed and returned by C (unsigned long long)';

my Pointer $ptr .= new;
ok SetPtrToPtr($ptr), 'Can pass an instantiated pointer with rw-trait to C';
is +$ptr, 42, 'Perl\'s rw variable was set by C (pointer)';

my CArray[CArray[uint8]] $buffer .= new;
$buffer[0] = CArray[uint8].new;

ReturnPointerToArray($buffer);
diag $buffer[0][$_] for ^4;
{
  my $cc = 0;
  for (2, 3, 4, 5) {
    my int8 $vv = $_;
    $buffer[0][$cc] = $vv;
    diag $buffer[0][$cc++];
  }
}

is VerifyBufferChanged(), 14, "buffer has changed";
#include <stdlib.h>
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT extern
#endif

DLLEXPORT void SetChar(signed char *chr) {
    *chr = 97;
}

DLLEXPORT signed char PassChar(signed char *chr) {
    return *chr;
}

DLLEXPORT void SetShort(short *sht) {
    *sht = 387;
}

DLLEXPORT short PassShort(short *sht) {
    return *sht;
}

DLLEXPORT void SetLong(long *lng) {
    *lng = 777;
}

DLLEXPORT long PassLong(long *lng) {
    return *lng;
}

DLLEXPORT void SetLongLong(long long *llg) {
    *llg = 15324;
}

DLLEXPORT long long PassLongLong(long long *llg) {
    return *llg;
}

DLLEXPORT void SetFloat(float *flt) {
    *flt = 6.66;
}

DLLEXPORT float PassFloat(float *flt) {
    return *flt;
}

DLLEXPORT void SetDouble(double *dbl) {
    *dbl = 12.12;
}

DLLEXPORT double PassDouble(double *dbl) {
    return *dbl;
}

DLLEXPORT void SetUChar(unsigned char *chr) {
    *chr = 153;
}

DLLEXPORT unsigned char PassUChar(unsigned char *chr) {
    return *chr;
}

DLLEXPORT void SetUShort(unsigned short *sht) {
    *sht = 387;
}

DLLEXPORT unsigned short PassUShort(unsigned short *sht) {
    return *sht;
}

DLLEXPORT void SetULong(unsigned long *lng) {
    *lng = 777;
}

DLLEXPORT unsigned long PassULong(unsigned long *lng) {
    return *lng;
}

DLLEXPORT void SetULongLong(unsigned long long *llg) {
    *llg = 15324;
}

DLLEXPORT unsigned long long PassULongLong(unsigned long long *llg) {
    return *llg;
}

DLLEXPORT int SetPtrToPtr(int **ptr) {
    if (ptr == NULL) {
        return 0;
    }

    *ptr = (int *)42;
    return 1;
}

char buffer[32];

DLLEXPORT int ReturnPointerToArray(void **ptr) {
    char index;
    for(index = 0; index < 32; index++)
        buffer[index] = 1;
    *ptr = (void *)buffer;
    return 1;
}

DLLEXPORT long long int VerifyBufferChanged() {
    return buffer[0] + buffer[1] + buffer[2] + buffer[3];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment