use strict; use warnings; use MyLibSWIG; use Win32; my $cnt_cback = \&my_connect_cb; for(1..100){ print("\n\n ########## TEST ITERATE : $_ ########## \n"); MyTest(); } sub MyTest { MyLibSWIG::MyRegister($cnt_cback); #Test: engage interpreter here while callback is being processed for (1..10){ print(sprintf("[%d] PRL: Doing something %d\n",Win32::GetCurrentThreadId(),$_)); Win32::Sleep(int(rand(100))); } MyLibSWIG::MyDeregister(); } sub my_connect_cb { print(sprintf("[%d] PRL: my_connect_cb called bConn = %d\n",Win32::GetCurrentThreadId(), $_[0])); } #### SV* MyConnectCbPerl = NULL; void* pMyConnectCbPerlCTX = NULL; extern void wrap_connect_cback_handler(BOOL bConnected); XS(_wrap_MyRegister) { { PFN_CONNECT_CALLBACK arg1 = (PFN_CONNECT_CALLBACK) 0 ; int argvi = 0; DWORD result; dXSARGS; if ((items < 1) || (items > 1)) { SWIG_croak("Usage: MyRegister(pfnConnectCallback);"); } { int status = IsValidCBRef(ST(0)); if (status == 0) { MyConnectCbPerl = (SV *)ST(0); //Save registered sub refrence pMyConnectCbPerlCTX = Perl_get_context(); //Save Perl Context arg1 = wrap_connect_cback_handler; //Register a wrapper function. When fired, the wrapper function invokes the perl subroutine. } } result = (DWORD)MyRegister(arg1); ST(argvi) = SWIG_From_unsigned_SS_long SWIG_PERL_CALL_ARGS_1((unsigned long)(result)); argvi++ ; XSRETURN(argvi); fail: SWIG_croak_null(); } } #### void wrap_connect_cback_handler(BOOL bConnected) { PERL_SET_CONTEXT(pMyConnectCbPerlCTX); SV * sv = NULL; sv = MyConnectCbPerl; if (sv == (SV*)NULL) croak("Internal error...MyConnectCbPerl not registered\n"); //Sleep(50); dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(bConnected))); PUTBACK; /* Call the Perl sub */ call_sv(sv, G_DISCARD); //PERL_SET_CONTEXT(pMyConnectCbPerlCTX); SPAGAIN; PUTBACK; FREETMPS; LEAVE; } #### ########## TEST ITERATE : 6 ########## [5528] LIB: MyRegister pfnConnectCallback = 54E310A5 [5528] PRL: Doing something 1 [6116] LIB: CallbackWorker firing ConnectCallback(0) [6116] PRL: my_connect_cb called bConn = 1 [5528] PRL: Doing something 2 [6116] LIB: CallbackWorker firing ConnectCallback(1) [6116] PRL: my_connect_cb called bConn = 0 [6116] LIB: CallbackWorker firing ConnectCallback(2) [6116] PRL: my_connect_cb called bConn = 1 [5528] PRL: Doing something 3 [6116] LIB: CallbackWorker firing ConnectCallback(3) [6116] PRL: my_connect_cb called bConn = 0 [5528] PRL: Doing something 4 [6116] LIB: CallbackWorker firing ConnectCallback(4) [6116] PRL: my_connect_cb called bConn = 0 [6116] PRL: my_connect_cb called bConn = 0 panic: pp_iter at F:\TEST\SWIG_API\Debug\run_cb.pl line 22. panic: pp_iter at F:\TEST\SWIG_API\Debug\run_cb.pl line 22.