【发布时间】:2015-11-10 02:58:09
【问题描述】:
我在 CentOS 6.5 上遇到过。正如我在网上搜索的那样,静态变量在使用动态库时在 Windows 和 Linux 上的行为不同。也就是说,Windows 会导致变量重复,而 Linux 不会,如下所示: http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
但是,当我写了一个小程序来验证这一点时,我发现 Linux 也会导致重复。这是我的小程序,包括四个文件:
(1) 啊.h
#ifndef A_H #define A_H #include <cstdio> static int b; extern "C" class A { public: int mem; A() { printf("A's address: %p\n", this); printf("B's address: %p\n", &b); } void print() { printf("%p: %d\n", this, mem); } ~A() { printf("DELETE A!!!!! %p\n", this); } }; extern A a; #endif
(2) A.cpp
#include "A.h" A a;
(3) d.cpp
#include "A.h" extern "C" void exec() { a.print(); }
(4) main.cpp
#include "A.h" #include <dlfcn.h> typedef void (*fptr) (); int main() { a.mem = 22; a.print(); void *handle; handle = dlopen("d.so", RTLD_LAZY); fptr exec = reinterpret_cast<fptr>(dlsym(handle, "exec")); (*exec)(); dlclose(handle); return 0; }
这是我编译和运行程序的方式:
g++ d.cpp A.cpp -shared -rdynamic -o d.so -ldl -I. -fPIC -g -std=c++1y g++ main.cpp A.cpp -ldl -I. -g -std=c++1y ./a.out
动态部分d.cpp 和静态部分main.cpp 都使用A.cpp 和A.h 中声明的变量a 和b。这是我机器上程序的结果:
A's address: 0x600f8c B's address: 0x600f90 0x600f8c: 22 A's address: 0x7fb8fe859e4c B's address: 0x7fb8fe859e50 0x7fb8fe859e4c: 0 DELETE A!!!!! 0x7fb8fe859e4c DELETE A!!!!! 0x600f8c
这让我很惊讶,因为全局变量a和静态变量b的地址在动态部分和静态部分应该是一样的。似乎对静态部分的a 的修改不会影响动态部分的a。有人可以回答我的问题,或者帮助找出程序中的一些错误(如果有的话)吗?
顺便说一句,老实说,在我正在做的另一个项目中,我发现动态库和静态库中全局变量的地址是相同的。但是那个项目太大了,我无法提供一个小程序来重现这种行为。
非常感谢!
【问题讨论】:
标签: c++ linux global-variables dynamic-library dlsym