关于动态链接中的全局变量

来源:互联网 发布:海会网络saas 编辑:程序博客网 时间:2024/05/17 22:59

《程序员自我修养》观后验证第二弹。

第一个例子:

有三个程序:

main.cpp

#include <stdio.h>int global_symbol = 300;extern void testso1();extern void testso2();int main(){    global_symbol++;    printf("the value of global symbol is %d\n", global_symbol);    testso1();    printf("the value of global symbol is %d\n", ++global_symbol);    testso2();    printf("the value of global symbol is %d\n", ++global_symbol);    return 0;}


so1.cpp

#include <stdio.h>int global_symbol = 500;void testso1(){        printf("the value of global symbol in so1 is %d\n", ++global_symbol);}


so2.cpp

#include <stdio.h>int global_symbol = 900;void testso2(){        printf("the value of global symbol in so2 is %d\n", ++global_symbol);}

编译的命令:

g++ -fPIC -c so1.cpp
g++ -fPIC -c so2.cpp
g++ -c main.cpp
g++ -shared -o so1.so so1.o
g++ -shared -o so2.so so2.o
g++  main.o so1.so so2.so


输出的结果是:

the value of global symbol is 301
the value of global symbol in so1 is 302
the value of global symbol is 303
the value of global symbol in so2 is 304
the value of global symbol is 305


原因:

a. 共享对象在编译时不能假设自己在进程虚拟地址空间中的位置。

b. 共享库在编译时,默认都把定义在模块内部的全局变量,当做定义在其他模块的全局变量。

c. 当共享模块被装载时,如果某个全局变量在可执行程序中拥有副本,那么动态链接器(在我的测试环境是/lib64/ld-linux-x86-64.so.2)就会把全局偏移表(GOT Global Offset Table)中的相应地址指向该副本,这样该变量在运行时实际上最终就只有一个实例。如果变量在共享库中被初始化,动态链接器还要将该初始化值复制到程序主模块中的变量副本;如果该全局变量在程序主模块中没有副本,那么GOT的相应地址就指向模块内部的该变量副本。(第二个例子验证)


得到的经验:

在动态库声明和操作全局变量的时候,不能认为在共享库的初始化的值,就是这个全局对象的真正初始值。


第二个例子:

将main.cpp中的 int global_symbol = 300; 改为extern int global_symbol; (即只做声明)

则输出的结果取决于链接的顺序

如果链接的命令是

g++  main.o so1.so so2.so

则输出为:

the value of global symbol is 501
the value of global symbol in so1 is 502
the value of global symbol is 503
the value of global symbol in so2 is 504
the value of global symbol is 505

如果链接的命令是

g++  main.o so2.so so1.so

则输出为:

the value of global symbol is 901
the value of global symbol in so1 is 902
the value of global symbol is 903
the value of global symbol in so2 is 904
the value of global symbol is 905

0 0
原创粉丝点击