[英]XS: Passing an external library's function a Perl XS callback
Disclaimer: asked over at perlmonks . 免责声明:在perlmonks询问 。
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. 我希望我正确地描述和描述我的问题......在XS中,我正在尝试将回调发送到外部库的函数,其中回调具有Perl特定的函数。 The XSUB is passed as a function pointer to an external C function. XSUB作为函数指针传递给外部C函数。 The XSUB callback being sent in turn calls back to a sub in the `main` perl application: 发送的XSUB回调又将回调到`main` perl应用程序中的sub:
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. 我认为这是因为外部库不理解被调用的perl函数。 Things work fine if I call the C `callback()` function directly though. 如果我直接调用C`callback()函数,事情就可以了。
Is there some magic that I can do to make the external library "see" the Perl C functions, or am I doing something wrong? 是否有一些魔法可以让外部库“看到”Perl C函数,或者我做错了什么?
Here's the code I'm testing with: 这是我正在测试的代码:
use warnings;
use strict;
use Inline ('C' => 'DATA', libs => '-lwiringPi');
init();
setInterrupt(27, 3);
# direct call
callback();
# on() triggers the external function and sends
# it 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. 如果我从回调中删除perl特定的C调用并且只执行`printf()`或其他纯C工作,那么事情就会在没有段错误的情况下继续进行。
Just came across this question and thought I'd give it my own answer as I did resolve it some time ago. 刚刚遇到这个问题并认为我会给出我自己的答案,就像我前一段时间解决它一样。
There were some important bits I was missing to set the Perl context, as well as within the C exec_perl_callback()
function. 我设置Perl上下文以及C exec_perl_callback()
函数中缺少一些重要的部分。
use warnings;
use strict;
use Inline 'C';
use Inline 'NoClean';
sub p_callback {
print "hello, world from perl!\n";
}
exec_perl_callback('p_callback');
__END__
__C__
#define PERL_NO_GET_CONTEXT
PerlInterpreter * mine;
void callback(char* perl_callback){
PERL_SET_CONTEXT(mine);
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
PUTBACK;
exec_perl_callback(perl_callback, G_DISCARD|G_NOARGS);
FREETMPS;
LEAVE;
}
Output: 输出:
hello world, from perl!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.