Re: Loading/registering multiple xsubs
you don't need that pushmark stuff if you're only chaining one xs module. what's documented in the ExtUtils::MakeMaker FAQ should work: http://perldoc.perl.org/ExtUtils/MakeMaker/FAQ.html#XS This is what's suggested there. BOOT: # boot the second XS file boot_Cool__Bar(aTHX_ cv); Cool::Bar is the name of the package. For one chained xs module, it's pretty simple. For more than one chain, there is some stack correction needed. The stuff described here seems to do the trick. http://lethargy.org/~jesus/writes/perl-dynaloader-obscurity this is what's suggested there: #define crutch_stack_wrap(directive) do { \ PUSHMARK(SP); \ PUTBACK; \ directive; \ SPAGAIN; \ PUTBACK; \ } while(0) BOOT: crutch_stack_wrap(boot_Base__Foo(aTHX_ cv)); crutch_stack_wrap(boot_Base__Bar(aTHX_ cv)); crutch_stack_wrap(boot_Base__Quux(aTHX_ cv)); glib and gtk seem to use the same sort of method, although it looks like some shortcuts were taken. -rob On Fri, Oct 14, 2011 at 5:00 AM, Torsten Schoenfeld kaffeeti...@gmx.de wrote: On 14.10.2011 08:11, Jeffrey Ratcliffe wrote: On 12 October 2011 16:00, Torsten Schoenfeldkaffeeti...@gmx.de wrote: Looks like Glib's mechanism is not C++-safe: specifically, the extern XS trick does not work because boot_Foo is already inside anextern C section. Try this: It didn't help - same error message. Weird; worked for me. The DynaLoader approach looks fine too, though.
Re: Loading/registering multiple xsubs
On 12 October 2011 16:00, Torsten Schoenfeld kaffeeti...@gmx.de wrote: Looks like Glib's mechanism is not C++-safe: specifically, the extern XS trick does not work because boot_Foo is already inside an extern C section. Try this: It didn't help - same error message. In the end, I took the mechanism used in Win32::GUI, putting in lib/Foo.pm sub bootstrap_subpackage { my($package) = @_; $package = 'Foo::' . $package; my $symbol = $package; $symbol =~ s/\W/_/g; no strict 'refs'; DynaLoader::dl_install_xsub( ${package}::bootstrap, DynaLoader::dl_find_symbol_anywhere( boot_$symbol ) ); { ${package}::bootstrap }; } bootstrap_subpackage 'Bar'; Regards Jeff
Re: Loading/registering multiple xsubs
On 12.10.2011 12:38, Jeffrey Ratcliffe wrote: Assuming we have Foo.xs Fo.pm Foo_Bar.xs how do I get Foo::Bar to load/boot/import at the same time as Foo on use Foo? You have to call Foo_Bar.xs' BOOT section (which wires up the xsubs) from Foo.xs' BOOT section. Look at Glib.xs' BOOT section for an example. For Gtk2 and below, this is handled by Gtk2::CodeGen-write_boot.
Re: Loading/registering multiple xsubs
On 12 October 2011 13:11, Torsten Schoenfeld kaffeeti...@gmx.de wrote: You have to call Foo_Bar.xs' BOOT section (which wires up the xsubs) from Foo.xs' BOOT section. Look at Glib.xs' BOOT section for an example. For Gtk2 and below, this is handled by Gtk2::CodeGen-write_boot. Thank you for your quick response. I'm still struggling, so I made a small example (attached), which fails to compile, trying to base the boot mechanism on that in Glib: foo.xs: In function 'void boot_Foo(PerlInterpreter*, CV*)': foo.xs:18: error: expected unqualified-id before string constant foo.xs:18: error: 'boot_Foo__Bar' was not declared in this scope Any ideas? Thanks Jeff Foo-0.01.tar.gz Description: GNU Zip compressed data
Re: Loading/registering multiple xsubs
On 12.10.2011 15:24, Jeffrey Ratcliffe wrote: On 12 October 2011 13:11, Torsten Schoenfeldkaffeeti...@gmx.de wrote: You have to call Foo_Bar.xs' BOOT section (which wires up the xsubs) from Foo.xs' BOOT section. Look at Glib.xs' BOOT section for an example. For Gtk2 and below, this is handled by Gtk2::CodeGen-write_boot. Thank you for your quick response. I'm still struggling, so I made a small example (attached), which fails to compile, trying to base the boot mechanism on that in Glib: foo.xs: In function 'void boot_Foo(PerlInterpreter*, CV*)': foo.xs:18: error: expected unqualified-id before string constant foo.xs:18: error: 'boot_Foo__Bar' was not declared in this scope Looks like Glib's mechanism is not C++-safe: specifically, the extern XS trick does not work because boot_Foo is already inside an extern C section. Try this: At the top of Foo.xs: extern C XS_EXTERNAL (boot_Foo__Bar); In its BOOT section: _gperl_call_XS (aTHX_ boot_Foo__Bar, cv, mark); If you want some backwards-compatibility, use #ifndef XS_EXTERNAL # define XS_EXTERNAL(name) XS(name) #endif