[32848] in Perl-Users-Digest
Perl-Users Digest, Issue: 4114 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Jan 12 00:09:37 2014
Date: Sat, 11 Jan 2014 21:09:03 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sat, 11 Jan 2014 Volume: 11 Number: 4114
Today's topics:
extending Perl with C (was: Question about language set <rweikusat@mobileactivedefense.com>
Re: extending Perl with C (was: Question about language <ben@morrow.me.uk>
Re: extending Perl with C <rweikusat@mobileactivedefense.com>
Re: Question about language setting <dave@invalid.invalid>
Re: Question about language setting <rweikusat@mobileactivedefense.com>
Re: Question about language setting <ben@morrow.me.uk>
Re: Question about language setting <rweikusat@mobileactivedefense.com>
Re: Question about language setting <dave@invalid.invalid>
Re: Question about language setting <ben@morrow.me.uk>
Re: Question about language setting <ben@morrow.me.uk>
Re: Question about language setting <dave@invalid.invalid>
Re: Question about language setting <rweikusat@mobileactivedefense.com>
Re: Question about language setting <ben@morrow.me.uk>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Fri, 10 Jan 2014 20:38:53 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: extending Perl with C (was: Question about language setting)
Message-Id: <87d2jzfu76.fsf_-_@sable.mobileactivedefense.com>
Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
[...]
>> [*] It is actually not really difficult to combine XS/C code and Perl
>> code without jumping through the hoop of creating a full-fledged
>> extension module, ie, I have a module here which can be used like this:
>>
>> use MAD::xso_loader '/path/to/shared_object.so';
>>
>> which creates an AUTOLOAD subroutine in the package using it which tries
>> to locate an otherwise undefined function in the shared object or
>> objects.
>
> chromatic's FFI also does this; the problem is that the C ABI doesn't
> provide any type information, and even when you know the types building
> a C function call from dynamic type information is not possible without
> assembler tricks. A general-purpose robust solution along these lines
> (even if it only went as far as Win32::API does on Win32) would be
> extremely useful.
"Perfection is the enemy of the good": I'm fine with using XS and all I
really want is 'implement a function (or some functions)' in XS/C and
link that together with an existing Perl program without either going through
'all of the h2xs stuff' or 'relying on transparent runtime
compilation/ re-compilation' (and autogenerated XS code), eg (actual
example), in some application, I need to decompose an IPv4 address range
into proper networks. There's an efficient algorithm for that (I
invented, although I likely wasn't the first one to do so) but it needs
access to 'fast' bit scanning operations usually available as machine
instruction and provided as 'gcc builtins' in a somewhat more portable
way. Enter
----------
/*
provide access to __builtin_clz
and ffs routines
$Id: bit_scan.xs,v 1.3 2011-12-08 21:38:49 rw Exp $
*/
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <strings.h>
MODULE = lib
int
do_ffs(v)
unsigned v
CODE:
RETVAL = ffs(v);
OUTPUT:
RETVAL
int do_fls(v)
unsigned v
CODE:
RETVAL = 32 - __builtin_clz(v);
OUTPUT:
RETVAL
-----------
(this code is owned by my employer and quoted for educational purposes)
> I've occasionally considered writing something which
> uses debug symbols to get the type information (like c2ph in the core
> distribution, but more portable); given that OSs are increasingly
> installing libraries with detached debug symbols rather than simply
> stripping them this might actually work.
I've also turned the racoon parser into a shared library so that I could
make an extension module out of that and I considered doing this in
order to provide automatic access to the various racoon
structures. After reading through the DWARF specification, however, I
quickly abandoned this idea in favour of writing functions creating 'Perl
data structures' from selected parts of the racoon ones by hand ...
------------------------------
Date: Fri, 10 Jan 2014 21:44:19 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: extending Perl with C (was: Question about language setting)
Message-Id: <j666qa-s8u1.ln1@anubis.morrow.me.uk>
Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
> Ben Morrow <ben@morrow.me.uk> writes:
> >
> > chromatic's FFI also does this; the problem is that the C ABI doesn't
> > provide any type information, and even when you know the types building
> > a C function call from dynamic type information is not possible without
> > assembler tricks. A general-purpose robust solution along these lines
> > (even if it only went as far as Win32::API does on Win32) would be
> > extremely useful.
>
> "Perfection is the enemy of the good": I'm fine with using XS and all I
> really want is 'implement a function (or some functions)' in XS/C and
> link that together with an existing Perl program without either going through
> 'all of the h2xs stuff' or 'relying on transparent runtime
> compilation/ re-compilation' (and autogenerated XS code), eg (actual
> example), in some application, I need to decompose an IPv4 address range
> into proper networks. There's an efficient algorithm for that (I
> invented, although I likely wasn't the first one to do so) but it needs
> access to 'fast' bit scanning operations usually available as machine
> instruction and provided as 'gcc builtins' in a somewhat more portable
> way. Enter
[...]
Yes, if you're writing your own XS (or XS-compatible C) it's not a
problem. However, turning that XS file into a 'proper' extension just
means adding a 3-line .pm and a 4-line Build.PL, so I'd generally do
that. (I never use h2xs.) That way it behaves and installs like a Perl
module, so I don't have to worry about installing custom .sos when I
copy stuff onto a production machine.
What *would* be really useful, though, is a proper FFI interface that
allowed you to dlopen an arbitrary .so and call functions in it. That's
what you were talking about before: if you tried to open libc.so with
dl_open_file and find setlocale with dl_find_symbol it would segfault
when you tried to call it, because setlocale isn't void setlocale(pTHX_
CV *). Perl 6 and Python both have something like this, so I'm slightly
surprised noone's written one for Perl yet (Win32::API aside).
> > I've occasionally considered writing something which
> > uses debug symbols to get the type information (like c2ph in the core
> > distribution, but more portable); given that OSs are increasingly
> > installing libraries with detached debug symbols rather than simply
> > stripping them this might actually work.
>
> I've also turned the racoon parser into a shared library so that I could
> make an extension module out of that and I considered doing this in
> order to provide automatic access to the various racoon
> structures. After reading through the DWARF specification, however, I
> quickly abandoned this idea in favour of writing functions creating 'Perl
> data structures' from selected parts of the racoon ones by hand ...
Yup, that's about where I got to...
Ben
------------------------------
Date: Sat, 11 Jan 2014 13:35:30 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: extending Perl with C
Message-Id: <87sisuvdy5.fsf@sable.mobileactivedefense.com>
Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
>> Ben Morrow <ben@morrow.me.uk> writes:
>> >
>> > chromatic's FFI also does this; the problem is that the C ABI doesn't
>> > provide any type information, and even when you know the types building
>> > a C function call from dynamic type information is not possible without
>> > assembler tricks.
[...]
>> "Perfection is the enemy of the good": I'm fine with using XS and all I
>> really want is 'implement a function (or some functions)' in XS/C and
>> link that together with an existing Perl
[...]
> Yes, if you're writing your own XS (or XS-compatible C) it's not a
> problem. However, turning that XS file into a 'proper' extension just
> means adding a 3-line .pm and a 4-line Build.PL, so I'd generally do
> that. (I never use h2xs.) That way it behaves and installs like a Perl
> module, so I don't have to worry about installing custom .sos when I
> copy stuff onto a production machine.
I'm usually building (pretty bare bones) Debian packages, so that's not
an issue. ATM, there are 51 one them, with the 52nd in development. The
initial attempt to manage all of this manually (on about a dozen
different installations spread all around the globe) broke down a few
years ago :-).
> What *would* be really useful, though, is a proper FFI interface that
> allowed you to dlopen an arbitrary .so and call functions in it. That's
> what you were talking about before: if you tried to open libc.so with
> dl_open_file and find setlocale with dl_find_symbol it would segfault
> when you tried to call it, because setlocale isn't void setlocale(pTHX_
> CV *).
This had helped here but I'm actually really writing C code and linking
that with Perl, the code I posted upthread was just the simplest example
I'm presently using (there's no way to get access to __builtin_clz by
using a library as this is really a 'built-in' gcc function which gets
replaced by the corresponding machine instruction for the target
architecture).
There is
http://search.cpan.org/~gaal/FFI-1.02/FFI.pm
(which I found by 'creatively' typing 'Perl FFI' in a Google search box)
but I'm unsure if I'd want to use that (would need to have a look at the
internals), considering that XS works nicely enough.
------------------------------
Date: Fri, 10 Jan 2014 11:16:10 +0000 (UTC)
From: "Dave Saville" <dave@invalid.invalid>
Subject: Re: Question about language setting
Message-Id: <fV45K0OBJxbE-pn2-pf7GgQddGGH5@paddington.bear.den>
On Wed, 8 Jan 2014 14:03:34 UTC, "Dave Saville" <dave@invalid.invalid>
wrote:
<snip>
It would appear that you can't trap this. :-(
I have tried with 5.8.2 and 5.16.0 and it would appear that in the
former case perl sets up its locale stuff *before* it ever gets around
to BEGIN and in either case setting any environmentals in BEGIN has no
effect.
use strict;
use warnings;
BEGIN
{
if ( 2.5 ne "2.5" )
{
printf STDERR "oh dear %f\n", 2.5;
}
printf STDERR "BEGIN\t%s\n", $ENV{LANG};
$ENV{LANG} = 'en_GB';
}
use Encode;
printf STDERR "MAIN\t%s \n", $ENV{LANG};
5.8.2
[T:\tmp]set lang=nl_NL
[T:\tmp]try.pl
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = (unset),
LANG = "nl_NL"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
BEGIN nl_NL 2.500000
MAIN en_GB 2.500000
5.16.0
oh dear 2,500000
BEGIN nl_NL 2,500000
Invalid version format (non-numeric data) at
u:/perl5/lib/5.16.0/constant.pm line 2.
BEGIN failed--compilation aborted at u:/perl5/lib/5.16.0/constant.pm
line 2.
Compilation failed in require at u:/perl5/lib/5.16.0/os2/Encode.pm
line 8.
BEGIN failed--compilation aborted at u:/perl5/lib/5.16.0/os2/Encode.pm
line 8.
Compilation failed in require at try.pl line 15.
BEGIN failed--compilation aborted at try.pl line 15.
So I think this cannot be fixed from *inside* a perl script. Although
setlocale() would fix the problem use of it trips the problem in the
first place. :-(
Thanks for all the help and discussion.
--
Regards
Dave Saville
------------------------------
Date: Fri, 10 Jan 2014 12:59:25 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Question about language setting
Message-Id: <87bnzkxaaa.fsf@sable.mobileactivedefense.com>
"Dave Saville" <dave@invalid.invalid> writes:
> On Wed, 8 Jan 2014 14:03:34 UTC, "Dave Saville" <dave@invalid.invalid>
> wrote:
>
> <snip>
>
> It would appear that you can't trap this. :-(
>
> I have tried with 5.8.2 and 5.16.0 and it would appear that in the
> former case perl sets up its locale stuff *before* it ever gets around
> to BEGIN and in either case setting any environmentals in BEGIN has no
> effect.
>
> use strict;
> use warnings;
> BEGIN
> {
> if ( 2.5 ne "2.5" )
> {
> printf STDERR "oh dear %f\n", 2.5;
> }
> printf STDERR "BEGIN\t%s\n", $ENV{LANG};
> $ENV{LANG} = 'en_GB';
> }
> use Encode;
> printf STDERR "MAIN\t%s \n", $ENV{LANG};
Not in this way, at least, as the locale-information from the
environment is applied to an actual process via
setlocale(LC_ALL, "");
But have you tried to load the Encode module with LC_ALL temporarily
reset to "C locale", ie somewhat like this[*]:
------------
use POSIX qw(locale_h);
use locale;
BEGIN {
setlocale(LC_ALL, 'C');
require mod;
setlocale(LC_ALL, '');
}
------------
[*] In case you're unconditionally overwriting the user's locale,
anyway, documenting this "I18N is not supported and using something
other than the "C" locale may or may not work" might be a more
honest way of dealing with this.
On UNIX(*) etc, you could also do something like this:
-------------
#!/usr/bin/perl
use POSIX qw(locale_h);
use locale;
BEGIN {
setlocale(LC_ALL, '');
if (sprintf('%f', 2.5) =~ /,/) {
print STDERR ("You won't spoil my precious bodily fluids!\n");
$ENV{LANG} = 'C';
exec($0, @ARGV);
}
}
printf("%f\n", 2.5);
-------------
------------------------------
Date: Fri, 10 Jan 2014 13:37:12 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Question about language setting
Message-Id: <8l95qa-cjj1.ln1@anubis.morrow.me.uk>
Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
>
> Not in this way, at least, as the locale-information from the
> environment is applied to an actual process via
>
> setlocale(LC_ALL, "");
>
> But have you tried to load the Encode module with LC_ALL temporarily
> reset to "C locale", ie somewhat like this[*]:
>
> ------------
> use POSIX qw(locale_h);
> use locale;
>
> BEGIN {
> setlocale(LC_ALL, 'C');
> require mod;
> setlocale(LC_ALL, '');
> }
> ------------
POSIX loads Carp, which was the source of this problem in the first
place.
Ben
------------------------------
Date: Fri, 10 Jan 2014 15:44:21 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Question about language setting
Message-Id: <87bnzjhmei.fsf@sable.mobileactivedefense.com>
Ben Morrow <ben@morrow.me.uk> writes:
> Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
>>
>> Not in this way, at least, as the locale-information from the
>> environment is applied to an actual process via
>>
>> setlocale(LC_ALL, "");
>>
>> But have you tried to load the Encode module with LC_ALL temporarily
>> reset to "C locale", ie somewhat like this[*]:
>>
>> ------------
>> use POSIX qw(locale_h);
>> use locale;
>>
>> BEGIN {
>> setlocale(LC_ALL, 'C');
>> require mod;
>> setlocale(LC_ALL, '');
>> }
>> ------------
>
> POSIX loads Carp, which was the source of this problem in the first
> place.
The setlocale C library function could also be made available via XS[*] or
Inline::C.
[*] It is actually not really difficult to combine XS/C code and Perl
code without jumping through the hoop of creating a full-fledged
extension module, ie, I have a module here which can be used like this:
use MAD::xso_loader '/path/to/shared_object.so';
which creates an AUTOLOAD subroutine in the package using it which tries
to locate an otherwise undefined function in the shared object or
objects.
------------------------------
Date: Fri, 10 Jan 2014 17:53:29 +0000 (UTC)
From: "Dave Saville" <dave@invalid.invalid>
Subject: Re: Question about language setting
Message-Id: <fV45K0OBJxbE-pn2-w26vn716mdyJ@paddington.bear.den>
On Fri, 10 Jan 2014 12:59:25 UTC, Rainer Weikusat
<rweikusat@mobileactivedefense.com> wrote:
> But have you tried to load the Encode module with LC_ALL temporarily
> reset to "C locale", ie somewhat like this[*]:
>
> ------------
> use POSIX qw(locale_h);
> use locale;
>
> BEGIN {
> setlocale(LC_ALL, 'C');
> require mod;
> setlocale(LC_ALL, '');
>
Fails - use POSIX falls down the same bear trap :-(
[T:\tmp]try.pl
Invalid version format (non-numeric data) at
u:/perl5/lib/5.16.0/Exporter.pm lin
e 3.
Compilation failed in require at u:/perl5/lib/5.16.0/os2/Fcntl.pm line
61.
Compilation failed in require at u:/perl5/lib/5.16.0/os2/POSIX.pm line
17.
BEGIN failed--compilation aborted at u:/perl5/lib/5.16.0/os2/POSIX.pm
line 17.
Compilation failed in require at try.pl line 3.
BEGIN failed--compilation aborted at try.pl line 3.
--
Regards
Dave Saville
------------------------------
Date: Fri, 10 Jan 2014 20:02:36 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Question about language setting
Message-Id: <s706qa-b1m1.ln1@anubis.morrow.me.uk>
Quoth Rainer Weikusat <rweikusat@mobileactivedefense.com>:
>
> The setlocale C library function could also be made available via XS[*] or
> Inline::C.
Yes, though that's somewhat harder.
> [*] It is actually not really difficult to combine XS/C code and Perl
> code without jumping through the hoop of creating a full-fledged
> extension module, ie, I have a module here which can be used like this:
>
> use MAD::xso_loader '/path/to/shared_object.so';
>
> which creates an AUTOLOAD subroutine in the package using it which tries
> to locate an otherwise undefined function in the shared object or
> objects.
chromatic's FFI also does this; the problem is that the C ABI doesn't
provide any type information, and even when you know the types building
a C function call from dynamic type information is not possible without
assembler tricks. A general-purpose robust solution along these lines
(even if it only went as far as Win32::API does on Win32) would be
extremely useful. I've occasionally considered writing something which
uses debug symbols to get the type information (like c2ph in the core
distribution, but more portable); given that OSs are increasingly
installing libraries with detached debug symbols rather than simply
stripping them this might actually work.
Ben
------------------------------
Date: Fri, 10 Jan 2014 20:41:14 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Question about language setting
Message-Id: <ag26qa-pi9.ln1@anubis.morrow.me.uk>
Quoth "Dave Saville" <dave@invalid.invalid>:
> On Fri, 10 Jan 2014 12:59:25 UTC, Rainer Weikusat
> <rweikusat@mobileactivedefense.com> wrote:
>
> > But have you tried to load the Encode module with LC_ALL temporarily
> > reset to "C locale", ie somewhat like this[*]:
> >
> > ------------
> > use POSIX qw(locale_h);
> > use locale;
> >
> > BEGIN {
> > setlocale(LC_ALL, 'C');
> > require mod;
> > setlocale(LC_ALL, '');
> >
>
> Fails - use POSIX falls down the same bear trap :-(
>
> [T:\tmp]try.pl
> Invalid version format (non-numeric data) at
> u:/perl5/lib/5.16.0/Exporter.pm lin
> e 3.
> Compilation failed in require at u:/perl5/lib/5.16.0/os2/Fcntl.pm line
> 61.
> Compilation failed in require at u:/perl5/lib/5.16.0/os2/POSIX.pm line
> 17.
> BEGIN failed--compilation aborted at u:/perl5/lib/5.16.0/os2/POSIX.pm
> line 17.
> Compilation failed in require at try.pl line 3.
> BEGIN failed--compilation aborted at try.pl line 3.
Hmm. The thought occurs, along the lines of Rainer's suggestion, that it
ought to be possible to bootstrap the XS part of POSIX.pm without
loading the Perl part... yes, this works:
require XSLoader;
#line 1 /opt/perl/lib/5.16.3/amd64-freebsd/POSIX.pm
XSLoader::load("POSIX");
POSIX::setlocale("LC_ALL", "C");
delete $POSIX::{$_} for keys %POSIX::;
The #line line is necessary to prevent XSLoader from falling back to
DynaLoader (which loads vars.pm, which has a 'use VERSION' line). It
must give the correct path to POSIX.pm on your system, with /
separators. Clearing out POSIX:: is necessary to avoid a whole lot of
'subroutine redefined' warnings when you load POSIX properly.
The #line hack could be avoided by using DynaLoader::dl_load_file and
dl_find_symbol directly, but that still needs to know the full path to
POSIX.dll (and you can't load Config to find it properly). I was hoping
it would be possible to avoid needing to clear POSIX:: by just looking
up 'setlocale' and then unloading the DLL, but these days XSUBs are
static functions and the only external symbol in the DLL is boot_POSIX.
Ben
------------------------------
Date: Sat, 11 Jan 2014 12:51:44 +0000 (UTC)
From: "Dave Saville" <dave@invalid.invalid>
Subject: Re: Question about language setting
Message-Id: <fV45K0OBJxbE-pn2-RPvlPBrNjHOj@paddington.bear.den>
On Fri, 10 Jan 2014 20:41:14 UTC, Ben Morrow <ben@morrow.me.uk> wrote:
>
> Quoth "Dave Saville" <dave@invalid.invalid>:
> > On Fri, 10 Jan 2014 12:59:25 UTC, Rainer Weikusat
> > <rweikusat@mobileactivedefense.com> wrote:
> >
> > > But have you tried to load the Encode module with LC_ALL temporarily
> > > reset to "C locale", ie somewhat like this[*]:
> > >
> > > ------------
> > > use POSIX qw(locale_h);
> > > use locale;
> > >
> > > BEGIN {
> > > setlocale(LC_ALL, 'C');
> > > require mod;
> > > setlocale(LC_ALL, '');
> > >
> >
> > Fails - use POSIX falls down the same bear trap :-(
> >
> > [T:\tmp]try.pl
> > Invalid version format (non-numeric data) at
> > u:/perl5/lib/5.16.0/Exporter.pm lin
> > e 3.
> > Compilation failed in require at u:/perl5/lib/5.16.0/os2/Fcntl.pm line
> > 61.
> > Compilation failed in require at u:/perl5/lib/5.16.0/os2/POSIX.pm line
> > 17.
> > BEGIN failed--compilation aborted at u:/perl5/lib/5.16.0/os2/POSIX.pm
> > line 17.
> > Compilation failed in require at try.pl line 3.
> > BEGIN failed--compilation aborted at try.pl line 3.
>
> Hmm. The thought occurs, along the lines of Rainer's suggestion, that it
> ought to be possible to bootstrap the XS part of POSIX.pm without
> loading the Perl part... yes, this works:
>
> require XSLoader;
>
> #line 1 /opt/perl/lib/5.16.3/amd64-freebsd/POSIX.pm
> XSLoader::load("POSIX");
> POSIX::setlocale("LC_ALL", "C");
> delete $POSIX::{$_} for keys %POSIX::;
>
> The #line line is necessary to prevent XSLoader from falling back to
> DynaLoader (which loads vars.pm, which has a 'use VERSION' line). It
> must give the correct path to POSIX.pm on your system, with /
> separators. Clearing out POSIX:: is necessary to avoid a whole lot of
> 'subroutine redefined' warnings when you load POSIX properly.
>
> The #line hack could be avoided by using DynaLoader::dl_load_file and
> dl_find_symbol directly, but that still needs to know the full path to
> POSIX.dll (and you can't load Config to find it properly). I was hoping
> it would be possible to avoid needing to clear POSIX:: by just looking
> up 'setlocale' and then unloading the DLL, but these days XSUBs are
> static functions and the only external symbol in the DLL is boot_POSIX.
Hi Ben
Argument "LC_ALL" isn't numeric in subroutine entry at
d:/usr/lib/perl/lib/5.16.
0/OS2/POSIX.pm line 2.
I could of course hard code the value from the .h file :-)
Finding the correct path on OS/2 is almost certainly *not* going to be
a problem. Because perl for OS/2 is a binary and because OS/2 uses
drive letters the chances of anyone installing in the same location as
the guy who built perl are very small. Therefoe we make use of
PERLLIB_PREFIX to find everything. However, it occurs to me that there
would be no way to build that # line on the fly. Not only to get the
path but also the perl version correct.
--
Regards
Dave Saville
------------------------------
Date: Sat, 11 Jan 2014 13:14:36 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Question about language setting
Message-Id: <8761pqd5j7.fsf@sable.mobileactivedefense.com>
"Dave Saville" <dave@invalid.invalid> writes:
> On Fri, 10 Jan 2014 20:41:14 UTC, Ben Morrow <ben@morrow.me.uk> wrote:
[...]
>> require XSLoader;
>>
>> #line 1 /opt/perl/lib/5.16.3/amd64-freebsd/POSIX.pm
>> XSLoader::load("POSIX");
>> POSIX::setlocale("LC_ALL", "C");
>> delete $POSIX::{$_} for keys %POSIX::;
>>
>> The #line line is necessary to prevent XSLoader from falling back to
>> DynaLoader (which loads vars.pm, which has a 'use VERSION' line). It
>> must give the correct path to POSIX.pm on your system, with /
>> separators. Clearing out POSIX:: is necessary to avoid a whole lot of
>> 'subroutine redefined' warnings when you load POSIX properly.
>>
>> The #line hack could be avoided by using DynaLoader::dl_load_file and
>> dl_find_symbol directly, but that still needs to know the full path to
>> POSIX.dll (and you can't load Config to find it properly). I was hoping
>> it would be possible to avoid needing to clear POSIX:: by just looking
>> up 'setlocale' and then unloading the DLL, but these days XSUBs are
>> static functions and the only external symbol in the DLL is boot_POSIX.
>
> Hi Ben
>
> Argument "LC_ALL" isn't numeric in subroutine entry at
> d:/usr/lib/perl/lib/5.16.
> 0/OS2/POSIX.pm line 2.
>
> I could of course hard code the value from the .h file :-)
That's what you have to do (and use the number instead of a string)
because there's no way to get access to the symbolic names without
loading the Perl part. However, what I was thinking was actually rather
something like this:
-----------
/* includes */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <locale.h>
MODULE = set_lc_all
char *set_lc_all(what)
char *what
CODE:
RETVAL = setlocale(LC_ALL, what);
OUTPUT:
RETVAL
----------
This is code written in the Perl eXtenSion language. It can be turned
into C with xsubpp, compiled into a shared object/ DLL and the
individual funtion can then be made available via DynaLoader. This
requires a certain one-time effort (I don't think I can legally post the
code I'm using but all in all, it is a lot less than 100 LOC) but I
found it more than occasionally useful that I can combine Perl and C
freely.
------------------------------
Date: Sun, 12 Jan 2014 03:52:09 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Question about language setting
Message-Id: <94g9qa-58n2.ln1@anubis.morrow.me.uk>
Quoth "Dave Saville" <dave@invalid.invalid>:
> On Fri, 10 Jan 2014 20:41:14 UTC, Ben Morrow <ben@morrow.me.uk> wrote:
> >
> > Hmm. The thought occurs, along the lines of Rainer's suggestion, that it
> > ought to be possible to bootstrap the XS part of POSIX.pm without
> > loading the Perl part... yes, this works:
> >
> > require XSLoader;
> >
> > #line 1 /opt/perl/lib/5.16.3/amd64-freebsd/POSIX.pm
> > XSLoader::load("POSIX");
> > POSIX::setlocale("LC_ALL", "C");
> > delete $POSIX::{$_} for keys %POSIX::;
> >
> > The #line line is necessary to prevent XSLoader from falling back to
> > DynaLoader (which loads vars.pm, which has a 'use VERSION' line). It
> > must give the correct path to POSIX.pm on your system, with /
> > separators. Clearing out POSIX:: is necessary to avoid a whole lot of
> > 'subroutine redefined' warnings when you load POSIX properly.
> >
> > The #line hack could be avoided by using DynaLoader::dl_load_file and
> > dl_find_symbol directly, but that still needs to know the full path to
> > POSIX.dll (and you can't load Config to find it properly). I was hoping
> > it would be possible to avoid needing to clear POSIX:: by just looking
> > up 'setlocale' and then unloading the DLL, but these days XSUBs are
> > static functions and the only external symbol in the DLL is boot_POSIX.
>
>
> Argument "LC_ALL" isn't numeric in subroutine entry at
> d:/usr/lib/perl/lib/5.16.
> 0/OS2/POSIX.pm line 2.
>
> I could of course hard code the value from the .h file :-)
Whoops... Yes, of course, you need to use the right constant.
> Finding the correct path on OS/2 is almost certainly *not* going to be
> a problem. Because perl for OS/2 is a binary and because OS/2 uses
> drive letters the chances of anyone installing in the same location as
> the guy who built perl are very small. Therefoe we make use of
> PERLLIB_PREFIX to find everything. However, it occurs to me that there
> would be no way to build that # line on the fly. Not only to get the
> path but also the perl version correct.
OK, well, in that case, you can replace the call to XSLoader::load with:
require XSLoader;
my $dll = "$ENV{PERLLIB_PREFIX}/5.16.0/OS2/auto/POSIX/POSIX.dll";
my $lib = DynaLoader::dl_load_file($dll, 0);
push(@DynaLoader::dl_librefs, $lib);
my $boot = DynaLoader::dl_find_symbol($lib, "boot_POSIX");
push(@DynaLoader::dl_modules, "POSIX");
my $xs = DynaLoader::dl_install_xsub(
"POSIX::bootstrap", $boot, $dll);
push(@DynaLoader::dl_shared_objects, $dll);
$xs->();
{ no warnings "redefine";
*POSIX::bootstrap = sub { };
}
(and this, I believe, avoids the need to clear POSIX:: as well).
Ben
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 4114
***************************************