Hi Monks. I'm on my 2nd day of learning XS here, and I can't seem to find any docs or examples on something I'm trying to get done here. On the C side of my code, I have a file descriptor (an integer), which is already open and working (actually it's not just any file descriptor, it's specifically a socket, but lets get there one step at a time). I want to make a callback to a perl function using call_sv(), and I want this file descriptor to appear as one of the callback arguments, in the form of a normal perl filehandle.
At one point, I was just passing the raw file descriptor into the perl callback as an integer, like so:
And then in the called-back perl code being called, I did:int conn = socket(.....); [...] ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(conn))); PUTBACK; cpretval = call_sv(the_coderef, G_SCALAR|G_EVAL|G_KEEPERR); SPAGAIN; if(SvTRUE(ERRSV)) { STRLEN n_a; log_helper(1,kidno,SvPV(ERRSV, n_a)); POPs; real_retval = 0; } else { if(cpretval != 1) croak("Return count from coderef callback != 1"); real_retval = POPi; } PUTBACK; FREETMPS; LEAVE;
sub the_callback_function { my ($conn) = @_; open(my $c,"+<&=$conn"); bless $c, 'IO::Socket::INET'; $c->autoflush(1); $c->send("Network data!\n"); .....
And surprisingly that worked fine, and sent "Network data!\n" out over the open socket. I'm sure there are some grave issues lurking in my heathen blessing of the filehandle to IO::Socket::INET without using any of its constructor code if I started using some of the other methods, but that's not terribly important at the moment.
So my next step was to eliminate the neccesity of having the perl side of things use that funky open(my $c,"+<&=$conn"); line by having the C code send an actual perl filehandle instead of a raw integer. I've gotten halfway there (I think), by creating a PerlIO* out of my integer in C, using:
However, attempting to do things like XPUSHs((SV*)conn_pio) are of course failing to do jack. How exactly does one properly push a PerlIO object onto the argument stack? It seems like there should be a function like io_2sv() to match the one I found named sv_2io(), but I don't see it, or anything that looks like it. Any ideas?PerlIO* conn_pio; conn_pio = PerlIO_fdopen(conn,"r+");
In reply to Sending PerlIO* to the stack for call_sv()? by ph713
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |