#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include "../mylib.h" #define MY_CXT_KEY "MyLib::_guts" XS_VERSION typedef struct { HV * Mapping; } my_cxt_t; START_MY_CXT static void lib_RegisterWorkDoneCallback_if( void *Data ) { dSP; dMY_CXT; printf( "Performing perl callback.\n" ); fflush( stdout ); ENTER; SAVETMPS; SV ** sv; sv = hv_fetch( MY_CXT.Mapping, (void*)&Data, sizeof(Data), FALSE ); if( sv == (SV**)NULL) croak("Internal error. No callback registered.\n"); PUSHMARK( sp ); XPUSHs( sv_2mortal( newSViv( (int) Data ) ) ); PUTBACK; perl_call_sv( *sv, G_DISCARD ); FREETMPS; LEAVE; } #include "const-c.inc" MODULE = MyLib PACKAGE = MyLib PREFIX = lib_ INCLUDE: const-xs.inc BOOT: { MY_CXT_INIT; MY_CXT.Mapping = (HV*)NULL; } int lib_RegisterWorkDoneCallback(A, Callback, Data) void *A SV *Callback void *Data CODE: { dMY_CXT; printf( "Registering Perl callback.\n" ); fflush( stdout ); if( MY_CXT.Mapping == (HV*)NULL ) MY_CXT.Mapping = newHV(); hv_store( MY_CXT.Mapping, (void*)&Data, sizeof( Data ), newSVsv( Callback ), 0 ); RETVAL = lib_RegisterWorkDoneCallback( A, &lib_RegisterWorkDoneCallback_if, Data ); } OUTPUT: RETVAL