sriniiyer has asked for the wisdom of the Perl Monks concerning the following question:
I am developing a xsubpp code for my project. In this I am using the call_sv() function in the .xs file to call a subroutine written in my Perl main program. Below are the program codes that I have written.
test.pl
Following is the XS code that I have written to handle these inputs.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");
TestXS.xs
The code compiles well without any errors or warnings. When the program is run and the callback function is called, the program goes into an infinite loop and throws and output like below: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 ==>> ...
Now, I am not able to understand the reason on why is it going into infinite loop. As an experiment, I edited the user-defined subroutine test_callback as below:
sub test_callback { print "Inside test_callback(): ", scalar(@_), " arguments.\n"; my $hash = shift; print "[IN_SUB] ", $hash, " reference to ", ref($hash), \n"; }
Now, this went pretty well without any infinite looping. To my understanding, there seems to something amiss when I am passing the hash reference to the callback function; no clue at all. Now, I'm not able to understand on where the problem exactly lies. Any help on this would be most welcome.
Thanking you in anticipation.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Callback function in xsubpp (each)
by tye (Sage) on Jul 30, 2013 at 18:54 UTC | |
by sriniiyer (Initiate) on Jul 31, 2013 at 05:03 UTC | |
by tye (Sage) on Jul 31, 2013 at 06:47 UTC | |
by sriniiyer (Initiate) on Aug 07, 2013 at 12:33 UTC | |
by sriniiyer (Initiate) on Jul 31, 2013 at 12:48 UTC |