2016-08-14 12 views
4

免責事項:perlmonksで尋ねられます。XS:外部ライブラリの関数をPerl XSコールバックに渡す

私は適切に私の問題を記述し、描写したいと思います... XSでは、コールバックにPerl固有の機能がある外部ライブラリの関数にコールバックを送信しようとしています。 XSUBは関数ポインタとして外部のC関数に渡されます。

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

// example extern call 

externFunc(&callback); 

このセグメンテーション違反:順番に送信されているXSUBのコールバックは、バック `main` perlのアプリケーションでサブに呼び出します。私は、外部ライブラリが呼び出されている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 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 

私はコールバック内から、perlの特定のCの呼び出しを削除し、ちょうど)( `printfの操作を行う場合は、`ここ

は、私がテストしていたコードですまたは他の純粋なCの仕事、物事はsegfaultなしで進みます。

+2

ISRからのPerlへの呼び出しは悪いアイデアのように思えます。間違ってしまうことがたくさんある。例:スレッド化された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; 
} 

出力:

hello world, from perl! 
関連する問題