Steve Hay <[EMAIL PROTECTED]> writes: >Nick Ing-Simmons wrote: >>Steve Hay <[EMAIL PROTECTED]> writes: >>>How does an XSUB find out what package it is compiled into? >>An XSUB isn't compiled into a package ;-)
Remember that. >> >>Its CV is entered into a stash but its "body" (which is what __PACKAGE__ >>refrers to) doesn't really have any meaning. That is to say >>"current package" (i.e. "current context op" i.e. PL_curcop) does not >>change when you call an XSUB. >> >>So CopSTASHPV(PL_curcop) gives you the name of the calling package >>(if I have right macro name...) >> >> >I spotted a couple of uses of $Package after sending my mail (e.g. in >dl_*.xs files). This works fine: > >void >foo(pkg="$Package") > char *pkg; >PPCODE: >{ > warn("I'm compiled into %s\n", pkg); >} > >but unfortunately my usual foo() XSUB wasn't such a good idea this time... > >I really want the package name in a BOOT: section, so the above is no >good :( I don't see why BOOT: should be any different to any other XSUB. BOOT: is still in scope of a MODULE line. Snag is you don't have control over the arguments it gets so typemaps are not much help. On the other hand the args you don't control XS side are useful... Remember that BOOT: is defining bootstrap method. So when you do bootstrap Foo; # i.e. Foo->bootstrap 'Foo' is passed in ST(0) to BOOT: And XSLoader('Foo') Defines then calls Foo->bootstrap. So BOOT: { warn("Booting package %s\n", SvPV_nolen(ST(0))); } Would print "Booting package Foo". But beware inheritance. i.e. if someone derives class Baz from Foo and then bootstrap's it you will get Baz not Foo as class name. > >CopSTASHPV(PL_curcop) [you got the name right] sounds hopeful, but >didn't quite output what I wanted: > >BOOT: >{ > warn("Booting package %s\n", CopSTASHPV(PL_curcop)); >} > >output "Booting package DynaLoader" :( I warned you ;-) - it isn't "in" a package. > >The Foo.pm file itself called XSLoader::load('Foo', $VERSION) within the >scope of "package Foo;". Is there any way of "getting back" to that? well you could eval_pv("caller(3)") or some such but this is getting very involved. Doing equivalent oc caller() in XS code is of course possible but very messy. > >The BOOT: section is destined for a .xs file to be INCLUDE'd by the .xs >files in each of two sub-directories: > >Common.xs >Foo/Foo.xs // INCLUDE's ../Common.xs >Bar/Bar.xs // INCLUDE's ../Common.xs > >I wanted it to automatically "know" what package it is in IT ISN'T "IN" A PACKAGE - it is only called from a (chain of) package(s). >since I can't >hard-code the package name into it If you explained why it needs to know and _exactly_ what it needs to know I may be able to help. >(other than putting separate copies >of it into each sub-directory's .xs file). Is that so bad? After all you are (probably) going to have to have a Foo.pm to call XSLoader('Foo') Have you considered writing Foo.xs.PL which generates Foo.xs ?