我在 CentOS 6.5 上遇到过。正如我在网上搜索的那样,静态变量在使用动态库时在 Windows 和 Linux 上的行为不同。也就是说,Windows 会导致变量重复,而 Linux 不会,就像这个: http ://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
但是,当我写了一个小程序来验证这一点时,我发现 Linux 也会导致重复。这是我的小程序,包括四个文件:
(1) 啊
#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
并在和中b
声明。这是我机器上程序的结果:A.cpp
A.h
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
动态部分。有人可以回答我的问题,或者帮助找出程序中的一些错误(如果有的话)吗?
顺便说一句,老实说,在我正在做的另一个项目中,我发现动态库和静态库中全局变量的地址是相同的。但是那个项目太大了,我不能提供一个小程序来重现这种行为。
非常感谢 !