Greets,
I have two XS modules, and I would like C symbols loaded by one to be
accessible from the other. The ultimate goal is to avoid including the Snowball
stemming library in the KinoSearch distribution, with all of its compilation
overhead, but instead load Lingua::Stem::Snowball and its associated shared
object and have the Snowball C API be accessible from within the KinoSearch
shared object.
This works fine on Mac OS X, but not on FreeBSD or Linux. The easiest way to
demonstrate the problem is to use Inline C.
Here's the Hello.pm perl module:
package Hello;
use Inline C => <<'END_C';
void
say_hello() {
printf("Greetings, earthlings!\n");
}
END_C
1;
Here's the hello_goodbye.pl perl script:
use strict;
use warnings;
use Hello;
use Inline C => <<'END_C';
extern void say_hello();
void
say_goodbye() {
say_hello();
printf("Prepare to die!\n");
}
END_C
say_goodbye();
The script works fine on OS X...
/Users/marvin/perltest/ $ perl hello_goodbye.pl
Greetings, earthlings!
Prepare to die!
/Users/marvin/perltest/ $
... but fails on Linux...
marvin@linlin:~/perltest$ /usr/local/debugperl/bin/perl5.10.0 hello_go
+odbye.pl
/usr/local/debugperl/bin/perl5.10.0: symbol lookup error:
/home/marvin/perltest/_Inline/lib/auto/hello_goodbye_pl_f0b6/hello_goo
+dbye_pl_f0b6.so:
undefined symbol: say_hello
marvin@linlin:~/perltest$
... and FreeBSD:
$ perl hello_goodbye.pl
/libexec/ld-elf.so.1: /usr/home/creamyg/perltest/_Inline/lib/auto/hell
+o_goodbye_pl_f0b6/hello_goodbye_pl_f0b6.so: Undefined symbol "say_hel
+lo"
$
Can anyone explain this behavior, and perhaps suggest a solution?
Update: RESOLVED
The default behavior for dynamically loading shared objects via the C function dlopen() is not to export symbols. To override when the loading happens via Perl, it's necessary to switch out XSLoader for the more complex but powerful Dynaloader and set some flags. Here's the patch to Lingua::Stem::Snowball:
Index: lib/Lingua/Stem/Snowball.pm
===================================================================
--- lib/Lingua/Stem/Snowball.pm (revision 97)
+++ lib/Lingua/Stem/Snowball.pm (working copy)
@@ -15,13 +15,17 @@
$VERSION = '0.95';
-@ISA = qw( Exporter );
+@ISA = qw( Exporter DynaLoader );
%EXPORT_TAGS = ( 'all' => [qw( stemmers stem )] );
@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
-require XSLoader;
-XSLoader::load( 'Lingua::Stem::Snowball', $VERSION );
+require DynaLoader;
+__PACKAGE__->bootstrap($VERSION);
+# Ensure that C symbols are exported so that other shared libaries (e
+.g.
+# KinoSearch) can use them. See Dynaloader docs.
+sub dl_load_flags { 0x01 }
+
# a shared home for the actual struct sb_stemmer C modules.
$stemmifier = Lingua::Stem::Snowball::Stemmifier->new;
Thanks to Rob for pointing me in the right direction.
References:
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.