程序结构为可执行文件源码main.c,动态库源码Func1.c,Func2.c,代码如下:
#include
extern void Func1();
extern void Func2();
extern int g_var;
int main()
{
Func1();
Func2();
return 0;
}
#include
int g_var = 11;
void Func1()
{
printf("Func1-->%d\n",g_var);
}
#include
int g_var = 22;
void Func2()
{
printf("Func2-->%d\n",g_var);
}
在CentOS5.5+gcc 4.1.2编译成功
g++ -g -shared -fPIC Func1.c -o libFunc1.so
g++ -g -shared -fPIC Func2.c -o libFunc2.so
g++ -g -L. -lFunc2 -lFunc1 -Wl,-rpath,. main.c -o main
./main 输出如下
Func1-->22
Func2-->22
为什么呢?
g++ -g -L. -lFunc2 -lFunc1-Wl,-rpath,. main.c -o main
因为动态链接器是先将Func2.so链接到进程虚拟空间,如果将编译命令变为
g++ -g -L. -lFunc1 -lFunc2-Wl,-rpath,. main.c -o main
则输出变为:
Func1-->11
Func2-->11
由此说明,不论进程所链接的动态库中有多少同名的全局变量,在进程虚拟空间内只有一份变量实体,所有的同名变量都会指向此实体,因此Func1.so和Func2.so中的g_var值是一致的。
再来修改一下main.c:
#include
extern void Func1();
extern void Func2();
int g_var;
int main()
{
Func1();
Func2();
return 0;
}
程序输出是什么呢?
Func1-->0
Func2-->0
没错,当可执行程序中已存在同名全局对象实体,则所有的动态库中的同名全局对象都会指向它。