Sharing global variables across dynamically load .so's - possible?

Sharing global variables across dynamically load .so's - possible?

Post by cly » Fri, 18 Jan 2002 09:43:50



Hi,

I am trying to share some global variables across dynamically loaded
.so's, on AIX using xlC compiler.  The following is an example:

//main.cc
#include "dummy.h"
#include <iostream>
#include <dlfcn.h>
using namespace std;
extern int wa;
typedef void (*fptr)(int a);

int main() {
  wa = 1;
  cout << wa << endl;

  void *handle = dlopen("empty.so",RTLD_LAZY);
  fptr dum = (fptr) dlsym(handle,"empty");
  (*dum)(2);
  cout << wa;
  dlclose(handle);

Quote:}

//empty.cc
#include "dummy.h"
#include <iostream>
using namespace std;
extern int wa;

extern "C" void empty(int a) {
  cout << wa << endl;
  wa = a;
  cout << wa << endl;

Quote:}

// dummy.h
int wa=0;

if empty.cc is compiled into empty.so using
xlC -c empty.cc
xlC -G -o empty.so empty.o

then when main.cc is executed, I'll get
1 <-- in main
0 <-- in empty.so
2 <-- in empty.so
1 <-- in main

However, what I am trying to do is to share it so that I'll get
1
1
2
2

I understand that global variables have global scope that only works in
one compilation unit.  Is there a way to make the above work?

Thanks!
Ron

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by David Schwart » Fri, 18 Jan 2002 10:05:58



> //main.cc
> #include "dummy.h"
> #include <iostream>
> #include <dlfcn.h>
> using namespace std;
> extern int wa;
> typedef void (*fptr)(int a);

> int main() {
>   wa = 1;
>   cout << wa << endl;

>   void *handle = dlopen("empty.so",RTLD_LAZY);
>   fptr dum = (fptr) dlsym(handle,"empty");
>   (*dum)(2);
>   cout << wa;
>   dlclose(handle);
> }

        Okay, I give up. Where is 'wa' supposed to live if there's only going
to be one of them? This code says 'extern int wa;' implying that 'wa'
lives in 'empty.so', but then it sets 'wa = 1' before loading
'empty.so'.

Quote:> //empty.cc
> #include "dummy.h"
> #include <iostream>
> using namespace std;
> extern int wa;

> extern "C" void empty(int a) {
>   cout << wa << endl;
>   wa = a;
>   cout << wa << endl;
> }

> // dummy.h
> int wa=0;

        Now, 'dummy.h' actually creates an int called 'wa', but it's included
by both .cc files, ensuring that they both create their own 'wa'.

Quote:> if empty.cc is compiled into empty.so using
> xlC -c empty.cc
> xlC -G -o empty.so empty.o

> then when main.cc is executed, I'll get
> 1 <-- in main
> 0 <-- in empty.so
> 2 <-- in empty.so
> 1 <-- in main

> However, what I am trying to do is to share it so that I'll get
> 1
> 1
> 2
> 2

        Well then it would certainly help if you only created 'wa' in one
place! Could you try adding some comments to the code above so that
others have a hope of understanding the reasoning.

        DS

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by cly » Fri, 18 Jan 2002 12:56:32


Thanks for your reply.  I have a new sample code that resembles more to my real
code, and makes it easier to understand why I am trying to do:

//blacs.h
extern int blah;

//blacs.cc
#include <stdio.h>
#include "blacs.h"
int blah = -1;

void changeblah(int a) { // change the value of blah
  blah = a;  }

void printblah() {        // print the value of blah
  printf("%d\n",blah);  }

//share.cc
#include <stdio.h>
#include "blacs.h"

extern void printblah(void);
extern void changeblah(int);

void foo() {
  printblah();                // -1
  changeblah(2);
  printblah();  }            // 2

//main.cc
#include <dlfcn.h>
#include <stdio.h>
#include "blacs.h"

typedef void (*fptr)();
extern void printblah(void);
extern void changeblah(int);

int main() {
  void *handle = (void *) dlopen("share.so",RTLD_LAZY);    // open the so
  fptr dum = (fptr) dlsym(handle,"foo__Fv");             // find the symbol
  (*dum)();                                            // call the func
  printblah();    // -1, want it to be 2

Quote:}

The code is compiled with these options
g++ -c blacs.cc
g++ -c share.cc
g++ -shared -o share.so share.o blacs.o
g++ main.cc blacs.o -ldl

Obviously this is caused by having 2 copies of blah in my code, one in a.out and
one in share.so.  But how do I make them share one copy?  I will be reading and
writing to blah (by calling the functions in blacs.o) in both share.so and a.out.

Thanks for your help!

Ron


>         Well then it would certainly help if you only created 'wa' in one
> place! Could you try adding some comments to the code above so that
> others have a hope of understanding the reasoning.

>         DS

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by David Schwart » Fri, 18 Jan 2002 13:21:29



> Obviously this is caused by having 2 copies of blah in my code, one in a.out and
> one in share.so.  But how do I make them share one copy?  I will be reading and
> writing to blah (by calling the functions in blacs.o) in both share.so and a.out.

        First off, stop creating two copies. In the .so file, make sure you
only have

extern int blah;

        DS

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by cly » Fri, 18 Jan 2002 13:59:35


This is already the case I think (#include "blacs.h").

Below is where I guess the problem is.  blah is created in blacs.o, so when I build the
.so with
g++ -shared -o share.so share.o blacs.o

and the executable with
g++ main.cc blacs.o -ldl

both of share.so and a.out link staticly to blacs.o and thus create their own copies of
blah.  But if I compile the .so without blacs.o, a.out seg faults since dlopen is not
happy about the undefined function calls.

Any ideas?

Ron



> > Obviously this is caused by having 2 copies of blah in my code, one in a.out and
> > one in share.so.  But how do I make them share one copy?  I will be reading and
> > writing to blah (by calling the functions in blacs.o) in both share.so and a.out.

>         First off, stop creating two copies. In the .so file, make sure you
> only have

> extern int blah;

>         DS

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by Paul Pluzhniko » Fri, 18 Jan 2002 16:30:21




Quote:> This is already the case I think (#include "blacs.h").

What is already the case?
You really should abandon the horrible "top posting" practice ...

Quote:

> Below is where I guess the problem is.  blah is created in blacs.o, so
when I build the
> .so with
> g++ -shared -o share.so share.o blacs.o

> and the executable with
> g++ main.cc blacs.o -ldl

> both of share.so and a.out link staticly to blacs.o and thus create their
own copies of
> blah.  But if I compile the .so without blacs.o, a.out seg faults since
dlopen is not
> happy about the undefined function calls.

Note that AIX shared libraries behave closer to Windows .DLLs,
than to any other UNIX shared libs.
On most other UNICes your  "link share.so without blacs.o in it"
would have worked.

You may want to ask the same question in comp.unix.aix,
however the answers you'll get there will probably involve
native xlc/ld, and not g++.

Quote:> Any ideas?

One way to solve your problem is to build a third shared object:
  g++ -shared -o blacs.so blacs.o
and then link both a.out and share.so to blacs.so

You'll get only one copy of blacs.so loaded into the process,
and it will have the (one and only) "blah" variable in it.

 
 
 

Sharing global variables across dynamically load .so's - possible?

Post by Jens-Uwe Mag » Sat, 19 Jan 2002 04:54:55



>This is already the case I think (#include "blacs.h").

>Below is where I guess the problem is.  blah is created in blacs.o, so when I build the
>.so with
>g++ -shared -o share.so share.o blacs.o

>and the executable with
>g++ main.cc blacs.o -ldl

>both of share.so and a.out link staticly to blacs.o and thus create their own copies of
>blah.  But if I compile the .so without blacs.o, a.out seg faults since dlopen is not
>happy about the undefined function calls.

Try -brtl to make the AIX symbol resolution more ELFish.

--
Jens-Uwe Mager  <pgp-mailto:62CFDB25>

 
 
 

1. Sharing shares across the Internet .. possible ??

create a user on your box
give that user permission to view a shared resource in the smb.conf
the person on the internet will have to add you machine IP and a name to
their HOSTS file may even have to login in to your domain.

could be tricky but it can work.

I connect to my ISP and then login to my domain which is a RH 6.0
server, I have full access to my office this way.

I'm not a big advocate of sharing info over the internet.  SMB can be a
big hole.

2. WINS Server for Linux

3. Sharing Load Across multiple nic's

4. any Linux PPTP guru's out there?

5. Sharing shares across the Internet .. possible ??

6. Lilo failure

7. Shared variable between main() and loaded shared library - dlopen()

8. getting xdbx to work on the sgi...

9. Dynamical loading with global variables with HP 10.20

10. Shared libraries and global variables

11. Dynamically Loaded Shared Libraries and dbx

12. Dynamically loading shared objects

13. Visibility of global variables in shared libraries