QuoteSimple.xs: In function ‘_call_perl’:
/usr/lib/x86_64-linux-gnu/perl/5.26/CORE/perl.h:176:16: error: ‘my_perl’ undeclared (first use in this function); did you mean ‘my_fork’?
# define aTHX my_perl
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
(...)
// C-Teil
(...)
static SV *my_callback;
static int
_call_perl()
{
dSP;
int count;
int retval;
ENTER; SAVETMPS; PUSHMARK(SP);
PUTBACK;
count = perl_call_sv((SV*)my_callback, G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Error");
retval = POPi;
}
// XS Teil
MODULE: ... PACKAGE: ...
BOOT:
my_callback = newSVsv(&PL_sv_undef);
void
set_my_callback(ctx,callback=0)
MPV::Simple ctx
SV * callback
CODE:
sv_setsv(my_callback,callback);
static int
call_perl(ctx)
MPV::Simple ctx
CODE:
{
int ret;
ret = _call_perl();
RETVAL = ret;
}
OUTPUT: RETVAL
1
2
$ctx->set_my_callback(sub {print "callback called\n";my $c = $a+$b; return $c;});
my $count = $ctx->call_perl();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use MPV::Simple;
my $ctx = MPV::Simple->new();
$ctx->set_property_string('input-default-bindings','yes');
$ctx->set_property_string('input-vo-keyboard','yes');
$ctx->set_property_string('osc','no');
my $userdata = "test";
my $data = $ctx->set_wakeup_callback(\&func,$userdata);
$ctx->initialize();
$ctx->command();
exit 0;
sub func {print "callback called \n"}
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
}
2019-01-13T18:32:10 Max_Perlbeginner[...]
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.
[...]
1
2
3
4
5
6
7
8
9
static int pipes[2];
[...]
new [...]
if ( pipe(pipes) < 0) {
printf("Pipe creation failed\n");
perror ("pipe");
exit(EXIT_FAILURE);
}
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
has_events(MPV__Simple* ctx)
CODE:
int ret;
int pipefd = pipes[0];
if (pipefd < 0)
ret = -1;
else {
struct pollfd pfds[1] = {
{ .fd = pipefd, .events = POLLIN },
};
// Wait until there are possibly new mpv events
poll(pfds,1,0);
if (pfds[0].revents & POLLIN) {
// Empty the pipe. Doing this before calling mpv_wait_event()
// ensures that no wakeups are missed. It's not so important to
// make sure the pipe is really empty (it will just cause some
// additional wakeups in unlikely corner cases).
char unused[256];
read(pipefd, unused, sizeof(unused));
ret = 1;
}
else {
ret = 0;
}
}
RETVAL = ret;
OUTPUT: RETVAL
2019-01-28T13:23:18 Max_PerlbeginnerHaha, danke für das Kompliment (als solches fass ich den Vorschlag einmal auf). Aber ich glaube mein Try-and-Error Vorgehen ist nur wenig lehrreich [...]
Quotezumal ich im April Prüfungen habe und mich mit dem Programmieren ein wenig zurückhalten muss.
QuoteIch versuche aber auf jeden Fall zumindest 1-2 Tage nach München zu kommen...
1
2
3
4
5
if(!current_perl) {
parent_perl = PERL_GET_CONTEXT;
current_perl = perl_clone(parent_perl, CLONEf_KEEP_PTR_TABLE);
PERL_SET_CONTEXT(parent_perl);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Uint32 add_timer_cb (Uint32 interval, void* param )
{
Uint32 ret_interval;
{
if(!PERL_GET_CONTEXT) {
PERL_SET_CONTEXT(current_perl);
}
[...]
}
return ret_interval;
}
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "const-c.inc"
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#define stdout PerlIO_stdout()
#ifndef SDL_PERL_DEFINES_H
#define SDL_PERL_DEFINES_H
#endif
PerlInterpreter *parent_perl = NULL;
extern PerlInterpreter *parent_perl;
PerlInterpreter *current_perl = NULL;
void
sdl_perl_atexit (void)
{
SDL_Quit();
}
Uint32 add_timer_cb (Uint32 interval, void* param )
{
Uint32 ret_interval;
{
if(!PERL_GET_CONTEXT) {
PERL_SET_CONTEXT(current_perl);
}
dSP;
int count;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(interval)));
PUTBACK;
count = call_pv(param,G_SCALAR);
SPAGAIN;
if (count != 1 ) croak("callback returned more than 1 value\n");
ret_interval = POPi;
PUTBACK;
FREETMPS;
LEAVE;
}
return ret_interval;
}
MODULE = SDLTimer PACKAGE = SDLTimer
INCLUDE: const-xs.inc
BOOT:
PL_perl_destruct_level = 2;
int
init ( flags )
Uint32 flags
CODE:
RETVAL = SDL_Init(SDL_INIT_TIMER);
atexit(sdl_perl_atexit);
OUTPUT:
RETVAL
MODULE = SDLTimer PACKAGE = SDLTimer::Time
SDL_TimerID
time_add_timer ( interval, cmd )
Uint32 interval
char *cmd
CODE:
if(!current_perl) {
parent_perl = PERL_GET_CONTEXT;
current_perl = perl_clone(parent_perl, CLONEf_KEEP_PTR_TABLE);
PERL_SET_CONTEXT(parent_perl);
}
RETVAL = SDL_AddTimer(interval, add_timer_cb, (void *)cmd);
OUTPUT:
RETVAL