stevieb has asked for the wisdom of the Perl Monks concerning the following question:
update: You can see code snips I ended up with that works are in Re: XS: Passing an external library's function a Perl XS callback.
Disclaimer: cross-posted at StackOverflow.
I hope I'm describing and depicting my issue properly... In XS, I'm trying to send a callback into an external library's function, where the callback has Perl specific functions. The XSUB is passed as a function pointer to an external C function. The XSUB callback being sent in turn calls back to a sub in the main perl application:
void callback(){ dSP; PUSHMARK(SP); call_pv("p_callback", G_DISCARD|G_NOARGS); } // example extern call externFunc(&callback);
This segfaults. I think it's because the external library doesn't understand the perl functions that are being called. Things work fine if I call the C callback() function directly though.
Is there some magic that I can do to make the external library "see" the Perl C functions, or am I doing something wrong?
Here's the code I'm testing with:
use warnings; use strict; use Inline ('C' => 'DATA', libs => '-lwiringPi'); init(); # the below call is a local XS function that # sets up the external function with the callback setInterrupt(27, 3); # direct call callback(); # on() triggers the external function to exec # the callback on(27); sub p_callback { print "in perl callback\n"; } __DATA__ __C__ #include <stdlib.h> #include <stdio.h> #include <wiringPi.h> void init(); void on(int pin); void off(int pin); void setInterrupt(int pin, int edge); void callback(); void init(){ printf("in init\n"); wiringPiSetup(); } void on(int pin){ pinMode(pin, 1); digitalWrite(pin, 1); } void off(int pin){ digitalWrite(pin, 0); pinMode(pin, 0); } void setInterrupt(int pin, int edge){ wiringPiISR(pin, edge, &callback); } void callback(){ dSP; PUSHMARK(SP); call_pv("p_callback", G_DISCARD|G_NOARGS); }
Output:
in init in perl callback Segmentation fault
If I remove the perl specific C calls from within the callback and just do a printf() or other pure-C work, things proceed without a segfault.
|
|---|