加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

XS:将外部库的函数传递给Perl XS回调

发布时间:2020-12-16 06:13:58 所属栏目:大数据 来源:网络整理
导读:免责声明: perlmonks被问及. 我希望我正确地描述和描述我的问题……在XS中,我正在尝试将回调发送到外部库的函数,其中回调具有Perl特定的函数. XSUB作为函数指针传递给外部C函数.发送的XSUB回调又将回调到`main` perl应用程序中的sub: void callback(){ dSP
免责声明: perlmonks被问及.

我希望我正确地描述和描述我的问题……在XS中,我正在尝试将回调发送到外部库的函数,其中回调具有Perl特定的函数. XSUB作为函数指针传递给外部C函数.发送的XSUB回调又将回调到`main` perl应用程序中的sub:

void callback(){
    dSP;
    PUSHMARK(SP);
    call_pv("p_callback",G_DISCARD|G_NOARGS);
}

// example extern call

externFunc(&callback);

这段错误.我认为这是因为外部库不理解被调用的perl函数.如果我直接调用C`callback()函数,事情就可以了.

是否有一些魔法可以让外部库“看到”Perl C函数,或者我做错了什么?

这是我正在测试的代码:

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 callbackn";
}

__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 initn");
    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);
}

输出:

in init
in perl callback
Segmentation fault

如果我从回调中删除perl特定的C调用并且只执行`printf()`或其他纯C工作,那么事情就会在没有段错误的情况下继续进行.

解决方法

刚刚遇到这个问题并认为我会给出我自己的答案,就像我前一段时间解决它一样.

我设置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;
}

输出:

hello world,from perl!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读