develooper Front page | perl.perl5.porters | Postings from December 2007

Re: How to load a "loadable object" that has a non-default file extension ?

Thread Previous | Thread Next
From:
Craig A. Berry
Date:
December 14, 2007 13:56
Subject:
Re: How to load a "loadable object" that has a non-default file extension ?
Message ID:
c9ab31fc0712141356n5a7aca61y2538f398c887cbbd@mail.gmail.com
On Dec 14, 2007 1:09 PM, Jan Dubois <jand@activestate.com> wrote:
> On Fri, 14 Dec 2007, Craig A. Berry wrote:
> > A better solution than changing the file extension would be changing
> > the name of the loadable object so you would have, for example
> > PL_PGPLOT.dll or Perl_DLL_PGPLOT.dll (or similar) for the Perl
> > extension and avoid the namespace collision with pgplot.dll in the
> > registry (or wherever it is the collision is happening). We've done
>
> This is actually what he was doing with $dl_dlext: By setting it to
> 'xs.dll' he essentially just tacked on 'xs' to the name, but kept the
> extension as is.
>
> The namespace collision happens at runtime in the loader: dynamic references
> are resolved against the library name, so if you load multiple files
> with the same library name, the loader maps all symbols for that library
> to just one instance (the first one loaded, I believe).  This is not
> an issue if you load libraries with full pathname at runtime and resolve
> symbols explicitly using GetProcAddress (dlopen() and dlsym() on Unix),
> but all symbols that need to be resolved implicitly by the loader use
> just the library name).
>
> > this on VMS for years. You need to create a C<mod2fname> built-in (see
> > as an example what's in vms/vms.c), load it as
> > C<DynaLoader::mod2fname>, and the existing infrastructure in
> > DynaLoader should take care of the rest.

> An interesting idea, but not backwards compatible, so it can't be
> introduced on Windows until Perl 5.12.

Is that really true?  The C<mod2fname> function would be loaded via
NewXSProto and thus I don't think would have to be a symbol exported
as part of the main Perl library or executable, so there's no binary
compatibility breakage there, though I could be missing something.

DynaLoader would have to be modified to add to the list of names it
looks for rather than just replacing what's there.  For package Foo,
Dynaloader on Windows already looks for Foo.dll and then libFoo.dll,
and then plain Foo (with no extension) so you would need to prepend
PL_Foo.dll or something like it to the list.  Side note: you can see
from the example below that it actually looks for Foo.dll twice for
some reason (this with ActiveState 5.8.8 build 817, though I see the
same thing with a locally-built 5.10.0 on VMS).

The only compatibility issue I can see is that you could not build
extensions the new way and install them on an older Perl, at least not
without requiring a newer DynaLoader.  It might be possible to avoid
that by putting PL_Foo.dll at the end rather than the beginning of the
search list.  Of course there are performance considerations with
looking for too many things that you aren't  likely to find.  I'm not
advocating anything in particular but just want the possibilities to
be known and understood.


C:\work>perl -MXSLoader -e "BEGIN {$ENV{PERL_DL_DEBUG}=10;} package
Foo; XSLoader::load q/Foo/;"
DynaLoader.pm loaded (C:/Perl/lib C:/Perl/site/lib ., \lib)
DynaLoader::bootstrap for Foo (auto/Foo/Foo.dll)
dl_findfile(-LC:/Perl/lib -LC:/Perl/site/lib -L. Foo)
 checking in C:/Perl/lib for Foo.dll
 checking in C:/Perl/lib for Foo.dll
 checking in C:/Perl/lib for libFoo.dll
 checking in C:/Perl/lib for Foo
 checking in C:/Perl/site/lib for Foo.dll
 checking in C:/Perl/site/lib for Foo.dll
 checking in C:/Perl/site/lib for libFoo.dll
 checking in C:/Perl/site/lib for Foo
 checking in . for Foo.dll
 checking in . for Foo.dll
 checking in . for libFoo.dll
 checking in . for Foo
dl_findfile found:
Can't locate loadable object for module Foo in @INC (@INC contains:
C:/Perl/lib C:/Perl/site/lib .) at C:/Perl/lib/DynaLoader.pm line 118
        DynaLoader::croak('Can\'t locate loadable object for module
Foo in @INC (@INC co...') called at C:/Perl/lib/DynaLoader.pm line 196
        DynaLoader::bootstrap('Foo') called at C:/Perl/lib/XSLoader.pm line 111
        XSLoader::bootstrap_inherit('Foo') called at -e line 1

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About