diff options
author | Ilya Zakharevich <ilya@math.berkeley.edu> | 2003-04-21 15:44:37 -0700 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2003-08-12 08:41:49 +0000 |
commit | eeb76f9196badba4477eec08c14bb1422c608d7f (patch) | |
tree | 0711b4c3f1a30b17298b4580b286e5ef8477383c /ext/DynaLoader | |
parent | 41ac6247f8e86c9d6b58d479f3b04f983d05c096 (diff) | |
download | perl-eeb76f9196badba4477eec08c14bb1422c608d7f.tar.gz |
XSLoader revisted
Message-ID: <20030422054437.GA8297@math.berkeley.edu>
(the XSLoader doc hunk; the h2xs looks like a behavioural change)
p4raw-id: //depot/perl@20634
Diffstat (limited to 'ext/DynaLoader')
-rw-r--r-- | ext/DynaLoader/XSLoader_pm.PL | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/ext/DynaLoader/XSLoader_pm.PL b/ext/DynaLoader/XSLoader_pm.PL index 9e6d42b3c1..9f3aaed83c 100644 --- a/ext/DynaLoader/XSLoader_pm.PL +++ b/ext/DynaLoader/XSLoader_pm.PL @@ -160,6 +160,164 @@ For more complicated interface see L<DynaLoader>. Many (most) features of DynaLoader are not implemented in XSLoader, like for example the dl_load_flags is not honored by XSLoader. +=head2 Migration from C<DynaLoader> + +A typical module using L<DynaLoader|DynaLoader> starts like this: + + package YourPackage; + require DynaLoader; + + our @ISA = qw( OnePackage OtherPackage DynaLoader ); + our $VERSION = '0.01'; + bootstrap YourPackage $VERSION; + +Change this to + + package YourPackage; + use XSLoader; + + our @ISA = qw( OnePackage OtherPackage ); + our $VERSION = '0.01'; + XSLoader::load 'YourPackage', $VERSION; + +In other words: replace C<require DynaLoader> by C<use XSLoader>, remove +C<DynaLoader> from @ISA, change C<bootstrap> by C<XSLoader::load>. Do not +forget to quote the name of your package on the C<XSLoader::load> line, +and add comma (C<,>) before the arguments ($VERSION above). + +Of course, if @ISA contained only C<DynaLoader>, there is no need to have the +@ISA assignment at all; moreover, if instead of C<our> one uses +backward-compatible + + use vars qw($VERSION @ISA); + +one can remove this reference to @ISA together with the @ISA assignment + +If no $VERSION was specified on the C<bootstrap> line, the last line becomes + + XSLoader::load 'YourPackage'; + +=head2 Backward compatible boilerplate + +If you want to have your cake and eat it too, you need a more complicated +boilerplate. + + package YourPackage; + use vars qw($VERSION @ISA); + + @ISA = qw( OnePackage OtherPackage ); + $VERSION = '0.01'; + eval { + require XSLoader; + XSLoader::load('YourPackage', $VERSION); + 1; + } or do { + require DynaLoader; + push @ISA, 'DynaLoader'; + bootstrap YourPackage $VERSION; + }; + +The parentheses about XSLoader::load() arguments are needed since we replaced +C<use XSLoader> by C<require>, so the compiler does not know that a function +XSLoader::load() is present. + +This boilerplate uses the low-overhead C<XSLoader> if present; if used with +an antic Perl which has no C<XSLoader>, it falls back to using C<DynaLoader>. + +=head1 Order of initialization: early load() + +I<Skip this section if the XSUB functions are supposed to be called from other +modules only; read it only if you call your XSUBs from the code in your module, +or have a C<BOOT:> section in your XS file (see L<perlxs/"The BOOT: Keyword">). +What is described here is equally applicable to L<DynaLoader|DynaLoader> +interface.> + +A sufficiently complicated module using XS would have both Perl code (defined +in F<YourPackage.pm>) and XS code (defined in F<YourPackage.xs>). If this +Perl code makes calls into this XS code, and/or this XS code makes calls to +the Perl code, one should be careful with the order of initialization. + +The call to XSLoader::load() (or bootstrap()) has three side effects: + +=over + +=item * + +if $VERSION was specified, a sanity check is done to insure that the versions +of the F<.pm> and the (compiled) F<.xs> parts are compatible; + +=item * + +The XSUBs are made accessible from Perl; + +=item * + +If the C<BOOT:> section was present in F<.xs> file, the code there is called. + +=back + +Consequently, if the code in F<.pm> file makes calls to these XSUBs, it is +convenient to have XSUBs installed before the Perl code is defined; for +example, this makes prototypes for XSUBs visible to this Perl code. +Alternatively, if the C<BOOT:> section makes calls to Perl functions (or +uses Perl variables) defined in F<.pm> file, they must be defined prior to +the call to XSLoader::load() (or bootstrap()). + +The first situation being much more frequent, it makes sense to rewrite the +boilerplate as + + package YourPackage; + use XSLoader; + use vars qw($VERSION @ISA); + + BEGIN { + @ISA = qw( OnePackage OtherPackage ); + $VERSION = '0.01'; + + # Put Perl code used in the BOOT: section here + + XSLoader::load 'YourPackage', $VERSION; + } + + # Put Perl code making calls into XSUBs here + +=head2 The most hairy case + +If the interdependence of your C<BOOT:> section and Perl code is +more complicated than this (e.g., the C<BOOT:> section makes calls to Perl +functions which make calls to XSUBs with prototypes), get rid of the C<BOOT:> +section altogether. Replace it with a function onBOOT(), and call it like +this: + + package YourPackage; + use XSLoader; + use vars qw($VERSION @ISA); + + BEGIN { + @ISA = qw( OnePackage OtherPackage ); + $VERSION = '0.01'; + XSLoader::load 'YourPackage', $VERSION; + } + + # Put Perl code used in onBOOT() function here; calls to XSUBs are + # prototype-checked. + + onBOOT; + + # Put Perl initialization code assuming that XS is initialized here + +=head1 LIMITATIONS + +To reduce the overhead as much as possible, only one possible location +is checked to find the extension DLL (this location is where C<make install> +would put the DLL). If not found, the search for the DLL is transparently +delegated to C<DynaLoader>, which looks for the DLL along the @INC list. + +In particular, this is applicable to the structure of @INC used for testing +not-yet-installed extensions. This means that the overhead of running +uninstalled extension may be much more than running the same extension after +C<make install>. + =head1 AUTHOR Ilya Zakharevich: extraction from DynaLoader. |