Discussion:
accessing global variables in .xs wrapped libraries
(too old to reply)
Dirk Koopman
2006-01-31 15:18:08 UTC
Permalink
Is there some 'official' perl way of setting global variables in a .xs
wrapped global library at runtime?

I have a (huge) legacy app that is (now) a shared library. I need to
call various routines in this shared library under the control of the
usual .xs wrapper mechanism and this is all just fine.

However some of this code relies on certain global variables in the app
being set up (you need to know that this app has several 100 potential
entry points, each requiring a different set of global variables to be
set [just don't ask, ok?]).

I know what these variables are called (or at least I can work it out)
and these are therefore findable thru things like dlsym() and its
friends.

So how do I find them and then set them (probably thru DynaLoader)? They
are (at least for now) just simple ints.
--
Dirk Koopman <***@tobit.co.uk>
--
Dirk Koopman <***@causeway.com>
Muppet
2006-01-31 16:20:49 UTC
Permalink
Post by Dirk Koopman
So how do I find them and then set them (probably thru DynaLoader)? They
are (at least for now) just simple ints.
You could use tie'd scalars for this. Create your perl-level variables from
perl, passing the c names to your tie, and tie them all to the same class. In
the FETCH and STORE routines, do the dlsym lookup and load or store the value.
If they'll be changed a lot, you might instead cache their addresses after
doing the dlsym lookup in TIESCALAR.

I've used this trick to tie a perl hash-like object to a fancy C key-query
object, and it didn't take a lot of code. I have *not* done it for scalars,
but i'm guessing it wouldn't be too hard.
--
muppet <scott at asofyet dot org>
Nick Ing-Simmons
2006-02-02 21:58:06 UTC
Permalink
Post by Muppet
Post by Dirk Koopman
So how do I find them and then set them (probably thru DynaLoader)? They
are (at least for now) just simple ints.
You could use tie'd scalars for this. Create your perl-level variables from
perl, passing the c names to your tie, and tie them all to the same class. In
the FETCH and STORE routines, do the dlsym lookup and load or store the value.
If they'll be changed a lot, you might instead cache their addresses after
doing the dlsym lookup in TIESCALAR.
If you can know the names of variables at XS build time a trick that works
well is #define to produce something that looks like a function

#define setFoo(x) foo = (x)

MODULE ...

void setFoo(int x)

Then normal XS wrapper gets created.

and perl code can say
setFoo(42);
Post by Muppet
I've used this trick to tie a perl hash-like object to a fancy C key-query
object, and it didn't take a lot of code. I have *not* done it for scalars,
but i'm guessing it wouldn't be too hard.
For scalars it is possible to do direct MAGIC get/set with a bit less
overhead than a full tie.

But if you have to lookup names at run time then tying ONE hash to
the XS code is a good plan so that

$tiedHash{varname} = 42;

Calls STORE passing key and value,
STORE does a dlsym() on the "key" gets a pointer and pokes value.
Loading...