-
-
Save Garland-g/d50b46ec411f5df5989d94478dc21ea7 to your computer and use it in GitHub Desktop.
Ugly hack for assigning Callables to CStruct members in Perl6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
C | |
Native library header (ui.h): | |
... | |
struct uiAreaHandler { | |
void (*Draw)(uiAreaHandler *, uiArea *, uiAreaDrawParams *); | |
#Skipping the rest | |
} | |
... | |
test.c, compiled to libtest.so: | |
#include "ui.h" | |
#include <stddef.h> | |
#Takes a function that has exactly the same signature as the function pointer in the struct | |
size_t get_pointer_Draw( void (*f)(uiAreaHandler *, uiArea *, uiAreaDrawParams *)) { | |
return f; | |
} | |
Perl6 NativeCall: | |
sub get_pointer_Draw( &f (Pointer, Pointer, Pointer) ) returns size_t is native("./test") { * } | |
#CStruct for native library | |
#See https://stackoverflow.com/questions/43543217/passing-pointer-to-pointer-in-perl-6-nativecall | |
class uiAreaHandler is repr('CStruct') { | |
has size_t $.Draw; | |
#This is really a Pointer, but Pointer is immutable. | |
#size_t and Pointer are the same size, but size_t is mutable. | |
submethod BUILD(:$Draw!) { | |
$!Draw = get_pointer_Draw($Draw); #$Draw is always a Callable | |
#Assign the function pointer (which is masquerading as size_t) to the struct member | |
#The native library's C code treats this as a pointer, so the function call works. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment