问题
I've got a variable called global_count that I would like to share between the shared library and the main part of the program (and ultimately other libs, but for now I've simplified the testcase).
Given the declaration of global_count in globals.cpp:
extern "C" {
int* global_count;
}
We compile to create a global.o file:
gcc -c global.cpp
shared.cpp below will be used to create shared.so:
#include <stdio.h>
#include "global.h"
extern "C" {
void init_global_count(int* xp) {
printf("Initialize global count to: %d\n", *xp);
global_count = xp;
};
void print_global_count(){
if(global_count) {
printf("global_count is: %d\n",*global_count);
} else {
printf("global_count* is not initialized!\n");
}
};
}
global.h:
extern "C" {
extern int* global_count;
}
main.cpp:
#include <stdlib.h>
#include <dlfcn.h>
#include <stdio.h>
#include "global.h"
int answer = 42;
int* gc_copy;
typedef void (*func)();
void (*init_global_count)(int*);
void (*print_global_count)();
void load(char* shared_lib){
void* handle;
handle = dlopen(shared_lib,RTLD_NOW | RTLD_GLOBAL) ;
printf("load:after dlopen\n");
if(!handle)
{
printf("DID NOT LOAD!\n");
fflush(stdout);
fputs (dlerror(), stderr);
exit(1);
} else {
printf("Loaded OK!\n");
fflush(stdout);
void (*init_global_count)(int*) = (void (*)(int*))dlsym(handle, "init_global_count");
(*init_global_count)(&answer);
void (*print_global_count)() = (void (*)())dlsym(handle, "print_global_count");
(*print_global_count)();
}
}
int main(){
printf("main...\n");
load((char*)"./shared.so");
if(global_count)
printf("main:global_count is: %d\n", *global_count);
return 0;
}
To compile the shared lib and main:
gcc -g -Wall -fno-omit-frame-pointer -fPIC -shared -o shared.so shared.cpp global.o
gcc -g -o main main.cpp global.o -ldl
Note that we're linking in global.o in both of those compilations.
Now we run it and the output is:
main...
load:after dlopen
Loaded OK!
Initialize global count to: 42
global_count is: 42
So the *global_count* reported from inside *print_global_count()* (defined in shared.cpp) is 42 as expected. However, global_count is not reported from main because the global_count pointer has not been initialized - so the global_count in main.cpp is not the same as the global_count in shared.cpp.
I'm wondering if it's possible to do what I'm trying to do here (to share some global data between a .so and the module that loads the .so)? If so, do I need to link differently?
回答1:
All objects in a shared library need to be compiled as position independent (-fpic
or -fPIC
). So linking in globals.o
into your shared library is in error.
You are actually creating two instances of the global_count
pointer. You are trying to print out a pointer value as a decimal integer from main
. The global pointer variable global_count
in the main
version is not yet initialized, so it has the starting value of all bytes set to 0
.
You can remove globals.o
from your shared library, and only have one instance of the global_count
variable in main. However, for the shared library to see the main
global variables, they have to be made visible to them. You can do this by adding -rdynamic
to the flags to gcc
in your link line for main
.
来源:https://stackoverflow.com/questions/15008599/sharing-global-data-between-a-shared-library-and-main