X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pod%2Fperlxs.pod;h=e6f1862e56f1678a0e808eb392a05ae69d6f3da9;hb=3b910f1cdd4f8ae1cc44d538e0b3182f132b4bf7;hp=0b6659631a68c2ad4954ef8a8a278b579227d64f;hpb=30d6fba6aa7467c9f9b076801c9a8093e7735500;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pod/perlxs.pod b/pod/perlxs.pod index 0b66596..e6f1862 100644 --- a/pod/perlxs.pod +++ b/pod/perlxs.pod @@ -276,6 +276,63 @@ some heuristic code which tries to disambiguate between "truly-void" and "old-practice-declared-as-void" functions. Hence your code is at mercy of this heuristics unless you use C as return value.) +=head2 Returning SVs, AVs and HVs through RETVAL + +When you're using RETVAL to return an C, there's some magic +going on behind the scenes that should be mentioned. When you're +manipulating the argument stack using the ST(x) macro, for example, +you usually have to pay special attention to reference counts. (For +more about reference counts, see L.) To make your life +easier, the typemap file automatically makes C mortal when +you're returning an C. Thus, the following two XSUBs are more +or less equivalent: + + void + alpha() + PPCODE: + ST(0) = newSVpv("Hello World",0); + sv_2mortal(ST(0)); + XSRETURN(1); + + SV * + beta() + CODE: + RETVAL = newSVpv("Hello World",0); + OUTPUT: + RETVAL + +This is quite useful as it usually improves readability. While +this works fine for an C, it's unfortunately not as easy +to have C or C as a return value. You I be +able to write: + + AV * + array() + CODE: + RETVAL = newAV(); + /* do something with RETVAL */ + OUTPUT: + RETVAL + +But due to an unfixable bug (fixing it would break lots of existing +CPAN modules) in the typemap file, the reference count of the C +is not properly decremented. Thus, the above XSUB would leak memory +whenever it is being called. The same problem exists for C. + +When you're returning an C or a C, you have make sure +their reference count is decremented by making the AV or HV mortal: + + AV * + array() + CODE: + RETVAL = newAV(); + sv_2mortal((SV*)RETVAL); + /* do something with RETVAL */ + OUTPUT: + RETVAL + +And also remember that you don't have to do this for an C. + =head2 The MODULE Keyword The MODULE keyword is used to start the XS code and to specify the package @@ -531,7 +588,7 @@ Here's a truly obscure example: bool_t rpcb_gettime(host,timep) - time_t &timep ; /* \$v{timep}=@{[$v{timep}=$arg]} */ + time_t &timep; /* \$v{timep}=@{[$v{timep}=$arg]} */ char *host + SvOK($v{timep}) ? SvPV($arg,PL_na) : NULL; OUTPUT: timep @@ -847,7 +904,7 @@ However, the generated Perl function is called in very C-ish style: If one of the input arguments to the C function is the length of a string argument C, one can substitute the name of the length-argument by -C in the XSUB declaration. This argument must be omited when +C in the XSUB declaration. This argument must be omitted when the generated Perl function is called. E.g., void @@ -1064,8 +1121,8 @@ then not push return values on the stack. Some people may be inclined to include an explicit C in the above XSUB, rather than letting control fall through to the end. In those situations C should be used, instead. This will ensure that -the XSUB stack is properly adjusted. Consult L for -other C macros. +the XSUB stack is properly adjusted. Consult L for other +C macros. Since C macros can be used with CODE blocks as well, one can rewrite this example as: @@ -1776,7 +1833,7 @@ double-colons (::), and declare C to be of that type: T_PTROBJ_SPECIAL if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) { IV tmp = SvIV((SV*)SvRV($arg)); - $var = ($type) tmp; + $var = INT2PTR($type, tmp); } else croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\") @@ -1790,6 +1847,11 @@ The INPUT and OUTPUT sections substitute underscores for double-colons on the fly, giving the desired effect. This example demonstrates some of the power and versatility of the typemap facility. +The INT2PTR macro (defined in perl.h) casts an integer to a pointer, +of a given type, taking care of the possible different size of integers +and pointers. There are also PTR2IV, PTR2UV, PTR2NV macros, +to map the other way, which may be useful in OUTPUT sections. + =head2 Safely Storing Static Data in XS Starting with Perl 5.8, a macro framework has been defined to allow @@ -1840,7 +1902,7 @@ Below is an example module that makes use of the macros. dMY_CXT; CODE: if (MY_CXT.count >= 3) { - warn("Already have 3 blind mice") ; + warn("Already have 3 blind mice"); RETVAL = 0; } else { @@ -1859,6 +1921,10 @@ Below is an example module that makes use of the macros. else RETVAL = newSVpv(MY_CXT.name[index - 1]); + void + CLONE(...) + CODE: + MY_CXT_CLONE; B @@ -1894,7 +1960,10 @@ of C. The MY_CXT_INIT macro initialises storage for the C struct. -It I be called exactly once -- typically in a BOOT: section. +It I be called exactly once -- typically in a BOOT: section. If you +are maintaining multiple interpreters, it should be called once in each +interpreter instance, except for interpreters cloned from existing ones. +(But see C below.) =item dMY_CXT @@ -1915,8 +1984,47 @@ then use this to access the C member dMY_CXT; MY_CXT.index = 2; +=item aMY_CXT/pMY_CXT + +C may be quite expensive to calculate, and to avoid the overhead +of invoking it in each function it is possible to pass the declaration +onto other functions using the C/C macros, eg + + void sub1() { + dMY_CXT; + MY_CXT.index = 1; + sub2(aMY_CXT); + } + + void sub2(pMY_CXT) { + MY_CXT.index = 2; + } + +Analogously to C, there are equivalent forms for when the macro is the +first or last in multiple arguments, where an underscore represents a +comma, i.e. C<_aMY_CXT>, C, C<_pMY_CXT> and C. + +=item MY_CXT_CLONE + +By default, when a new interpreter is created as a copy of an existing one +(eg via C<new()>>), both interpreters share the same physical +my_cxt_t structure. Calling C (typically via the package's +C function), causes a byte-for-byte copy of the structure to be +taken, and any future dMY_CXT will cause the copy to be accessed instead. + +=item MY_CXT_INIT_INTERP(my_perl) + +=item dMY_CXT_INTERP(my_perl) + +These are versions of the macros which take an explicit interpreter as an +argument. + =back +Note that these macros will only work together within the I source +file; that is, a dMY_CTX in one source file will access a different structure +than a dMY_CTX in another source file. + =head1 EXAMPLES File C: Interface to some ONC+ RPC bind library functions.