2016-08-14 5 views
4

면책 조항 : perlmonks에 질문하십시오.XS : 외부 라이브러리의 함수를 Perl XS 콜백에 전달

필자는 제대로 문제를 기술하고 묘사하고 싶습니다 ... XS에서 콜백에 Perl 특정 기능이있는 외부 라이브러리 함수로 콜백을 보내려고합니다. XSUB는 외부 C 함수에 대한 함수 포인터로 전달됩니다. 다시 전송되는 XSUB 콜백은 다시 하위에`main` 펄 응용 프로그램에서 호출

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

// example extern call 

externFunc(&callback); 

이 세그먼테이션 폴트 (segfault). 나는 외부 라이브러리가 호출되는 perl 함수를 이해하지 못하기 때문이라고 생각한다. 내가`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 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); 
} 

출력 :

in init 
in perl callback 
Segmentation fault 

내가 콜백 내에서 펄 특정 C 호출을 제거하고 단지) (A '의 printf를 할 경우`여기

내가 함께 테스트하고있어 코드의 또는 다른 순수한 C 작업의 경우 세그먼트없이 진행됩니다.

+2

나쁜 생각처럼 보인다. 잘못 될 수있는 많은 것들이 있습니다. 예를 들어 : 스레드 된 Perl을 실행하고 있고 다른 스레드에서 호출 된 ISR입니까? – nwellnhof

+0

@nwellnhof 전 핸들링을 방해하는 새로운 브랜드이고 C newb이기 때문에 큰 학습 곡선입니다 :) 진행하기 전에 여기에서 조사를해야한다고 지적했습니다. 감사! – stevieb

답변

1

방금 ​​전에이 문제를 해결 한 것처럼 내 자신의 대답을 줄 것이라고 생각했습니다.

C exec_perl_callback() 함수뿐만 아니라 Perl 컨텍스트를 설정하기 위해 누락 된 몇 가지 중요한 비트가 있습니다.

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

출력

: ISR에에서 펄에 호출

hello world, from perl! 
관련 문제