use ExtUtils::testlib; use TestXS; sub test_callback { print "Inside test_callback(): ", scalar(@_), " arguments.\n"; my $hash = shift; print "[IN_SUB]\n"; for (keys %$hash) { print "\t", $_, " ==>> ", $hash->{$_}, "\n"; } } # # # # # MAIN # # # # # my $file_list = { "/tmp/" => undef, "/tmp/TestXS" => undef, "/usr/include/" => undef, }; TestXS::callback_sub($file_list, "test_callback"); #### int call_perl_sub(SV *routine, SV *data_hash) { dSP; /* Get the stack pointer. */ /* Allocate the temporary memory location. */ ENTER; SAVETMPS; PUSHMARK(SP); /* Get the temporary stack pointer. */ XPUSHs(sv_2mortal(data_hash)); /* Push the hash onto the stack. */ PUTBACK; /* Call the PERL subroutine, ignoring its return value. */ call_sv(routine, G_DISCARD); /* Free the allocated memory. */ FREETMPS; LEAVE; } /* End of function: call_perl_sub() */ MODULE = TestXS PACKAGE = TestXS void callback_sub(file_list, callback) SV *file_list; SV *callback; CODE: HV *inp_file_list = (HV *) SvRV(file_list); HE *next_entry = NULL; /* Initialize the iterator. */ hv_iterinit(inp_file_list); for (next_entry = hv_iternext(inp_file_list); next_entry != NULL; next_entry = hv_iternext(inp_file_list)) { I32 keylen = 0; SV *entry_val = hv_iterval(inp_file_list, next_entry); char *filepath = hv_iterkey(next_entry, &keylen); sv_setpv(entry_val, "Marked."); fprintf(stderr, "[UPDATED] %s ==>> %s\n", filepath, SvPV_nolen(entry_val)); call_perl_sub(callback, SvREFCNT_inc(file_list)); } #### [UPDATED] /usr/include/ ==>> Marked. [IN_SUB] /usr/include/ ==>> Marked. /tmp ==>> /tmp/TestXS ==>> [UPDATED] /usr/include/ ==>> Marked. [IN_SUB] /usr/include/ ==>> Marked. /tmp ==>> /tmp/TestXS ==>> [UPDATED] /usr/include/ ==>> Marked. [IN_SUB] /usr/include/ ==>> Marked. /tmp ==>> /tmp/TestXS ==>> [UPDATED] /usr/include/ ==>> Marked. [IN_SUB] /usr/include/ ==>> Marked. /tmp ==>> /tmp/TestXS ==>> ... #### sub test_callback { print "Inside test_callback(): ", scalar(@_), " arguments.\n"; my $hash = shift; print "[IN_SUB] ", $hash, " reference to ", ref($hash), \n"; }