unlinker has asked for the wisdom of the Perl Monks concerning the following question:
Thanks to the help from the wise monks here, (see A few very basic questions about Extending Perl), I have made slow but steady progress in writing XS routines. As mentioned there, I want to integrate a C Library (whose shared object is available but not the source) to manage sessions. Everything works as I want, except for a lurking suspicion that being a noob, I have left out something important :)
Here is the standalone XSUB that essentially mimics the C Library that I want to integrate. I have implemented only 3 of the important functions here — a function that allocates some space and sends me a handle to that space (perl sees the pointer to a struct cast to integer); a function that gets the variables of that struct; and finally a function that frees the allocated space when my session is over. I need to pass the handle (an int in perl) to access each function in the Library. Of course this is only a sample implementation of what the C-library provides with all the other parameters removed:
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" typedef struct { int id; int desc; char* str; } session; MODULE = MySession PACKAGE = MySession void new(str) char* str PREINIT: session* tmppt; int tmpint; PPCODE: tmppt = (session*) malloc(sizeof(session)); tmppt->id = 42; tmppt->desc = 4242; tmppt->str = str; tmpint = (int) tmppt; EXTEND(SP, 1); PUSHs(sv_2mortal(newSViv((int) tmppt))); MODULE = MySession PACKAGE = MySession void get(hndl) int hndl PREINIT: session* tmppt; PPCODE: tmppt = (session *)hndl; EXTEND(SP, 3); PUSHs(sv_2mortal(newSViv(tmppt->id))); PUSHs(sv_2mortal(newSViv(tmppt->desc))); PUSHs(sv_2mortal(newSVpv(tmppt->str, 0))); MODULE = MySession PACKAGE = MySession void disconnect(hndl) int hndl CODE: free((session*) hndl);
And here is a test file for the routines:
#!/usr/bin/env perl use strict; use warnings; use ExtUtils::testlib; use MySession; my $x = MySession::new("Session ID Goes Here"); print "$x\n"; my ($p, $q, $str) = MySession::get($x); print "$p\n$q\n$str\n"; my $y = MySession::new("Another Session ID Goes Here"); print "$y\n"; ($p, $q, $str) = MySession::get($y); print "$p\n$q\n$str\n"; my $z = MySession::new("Yet Another Session ID Goes Here"); print "$z\n"; ($p, $q, $str) = MySession::get($z); print "$p\n$q\n$str\n"; MySession::disconnect($x); MySession::disconnect($y); MySession::disconnect($z); __END__
Now for the questions:
- The session struct contains a pointer to a string. This string is passed from the Perl code. I am assuming that perl will free string so I do not specifically free the memory associated with the string. I just free the memory associated with the struct as a whole. Is this correct?
- I want to now use the functions implemented here as methods in a Moose class. I can always define a module (as I have done here) say MySession and "use" this class in my Moose class and thereby access those functions. But surely there must be a better way? Can you help me with integrating this XSUB concisely with my Moose class or direct me to documentation on how this can be achieved?
- Finally, any pointers on improving the XSUB itself (as implemented here) and the test script would be great.
Thank you once again for your patience and your wisdom
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: More Questions about Extending Perl
by Anonyrnous Monk (Hermit) on Jan 02, 2011 at 13:28 UTC | |
by unlinker (Monk) on Jan 02, 2011 at 16:37 UTC | |
by andal (Hermit) on Jan 03, 2011 at 09:13 UTC |