Skip to content

Instantly share code, notes, and snippets.

@Garland-g
Last active August 22, 2018 00:28
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 Garland-g/d50b46ec411f5df5989d94478dc21ea7 to your computer and use it in GitHub Desktop.
Save Garland-g/d50b46ec411f5df5989d94478dc21ea7 to your computer and use it in GitHub Desktop.
Ugly hack for assigning Callables to CStruct members in Perl6
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