Welcome 微信登录

首页 / 操作系统 / Linux / Linux系统下DSO同名全局变量浅析

    最近重温了一下《程序员修养》,又搞懂了一些叽里旮旯的问题,现将DSO同名全局变量问题进行简单小结,具体的讲解请看《程序员修养》一书。 程序员的自我修养—链接、装载与库.pdf版下载在Linux公社的1号FTP服务器里,下载地址:FTP地址:ftp://www.linuxidc.com用户名:www.linuxidc.com密码:www.muu.cc在 2011年LinuxIDC.com3月程序员的自我修养—链接、装载与库下载方法见 http://www.linuxidc.net/thread-1187-1-1.html    程序结构为可执行文件源码main.c,动态库源码Func1.c,Func2.c,代码如下:        #include <stdio.h>    extern void Func1();
    extern void Func2();    extern int g_var;    int main()
   {
        Func1();
        Func2();
  
        return 0;
   }      #include <stdio.h>   int g_var = 11;   void Func1()
   {
       printf("Func1-->%d ",g_var);
   }
      #include <stdio.h>   int g_var = 22;   void Func2()
   {
      printf("Func2-->%d ",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 <stdio.h>    extern void Func1();
    extern void Func2();    int g_var;    int main()
   {
        Func1();
        Func2();
  
        return 0;
   }   程序输出是什么呢?   Func1-->0
   Func2-->0   没错,当可执行程序中已存在同名全局对象实体,则所有的动态库中的同名全局对象都会指向它。   以上两种情况,究其原因,都是动态链接机制惹的祸,具体的分析各位看官,拜读一下《程序员的自我修养—链接、装载与库》吧,此处只为抛砖引玉,就不再班门弄斧了!