Thread Perl Funktion von XS aufrufen (16 answers)
Opened by Max_Perlbeginner at 2019-01-02 16:28

Max_Perlbeginner
 2019-01-13 19:32
#189447 #189447
User since
2016-04-04
101 articles
BenutzerIn
[default_avatar]
Ich möchte ein Perlmodul zu dem Videoplayer MPV erstellen (bzw. besser zu dessen zugrundeliegender Bibliothek libmpv, siehe https://mpv.io/ bzw. die Github Seite). Im Grundsatz klappt es auch ganz gut.

Allerdings ist es erforderlich, MPV in einer Event Schleife auszuführen. Problematisch ist dies v.a., wenn man libmpv zusammen mit einer GUI einsetzen will, die ja ein eigene Ereignisschleife hat. Hierfür ist in der C Bibliothek die Funktion set_wakeup_callback da. Dieser kann man eine Funktion übergeben, die aufgerufen wird, wenn ein neues Ereignis eingetreten ist. Allerdings geschieht dies aus einem zufälligen C-Thread.

In XS habe ich ein Proxy Callback, dessen einzige Aufgabe es ist, meinen echten Perl Callback aufzurufen (mit call_sv). der Perl Callback ist in einer globalen Variable gespeichert, ebenso wie Daten, die an den Perl Callback übergeben werden sollen (in meinem Fall ein Tcl Widget, das dann ein virtuelles Tcl Ereignis ausführen soll). Mittels perl_clone vor dem Aufruf von call_sv im Proxy Callback habe ich es geschafft, dass mein Media Player nicht wegen eines Speicherzugrifffehlers abstürzt. Allerdings erhalte ich dennoch vereinzelt einen Speicherzugriffsfehler. Zudem wird der Perl Callback bzw. das Tcl Ereignis nur ein einziges Mal aufgerufen.

Hier eine kleine Testdatei:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use Tcl::Tk;
use MPV::Simple;
my $int =Tcl::Tk->new();
my $mw = $int->mainwindow();
# Bind MPV Event to the event handler
$mw->bind('<<MPV>>' => \&on_mpv);

my $f = $mw->Frame(-background => "green",-width => 640, -height => 480)->pack(-expand =>1,-fill => "both");
my $id;
$id = $f->id();

# MPV part
$MPV::Simple::callback_data=$f;
my $ctx = MPV::Simple->new();
$ctx->initialize();
$ctx->set_wakeup_callback(\&wakeup_callback, \$f);
$ctx->set_property_string("wid",$id);
$ctx->command("loadfile", "./einladung2.mp4");

$mw->Button(-text => "Restart", -command => sub {$ctx->command("loadfile", "./einladung2.mp4")})->pack;
$int->MainLoop();

# Wake up callback
sub wakeup_callback {
print "IN WAKEUP\n";
$int->Eval("event generate $f <<MPV>> -when head" or die "Did not work\n");
return;
}

# Event handler
sub on_mpv {
print "YEAH, im Event handler\n";
return
}


Eigtl. müsste immer, wenn man auf Restart klickt, ein Ereignis gesendet werden (und somit "Yeah,..." erscheinen").

Im Voraus lieben Dank für jede Hilfe,
Max

View full thread Perl Funktion von XS aufrufen