CentOS 6.5で遭遇しました。私がオンラインで検索したように、動的ライブラリを使用する場合、静的変数は Windows と Linux で異なる動作をします。つまり、次のように、Windows では変数の重複が発生しますが、Linux では発生しません 。
しかし、これを検証する小さなプログラムを書いたところ、Linux でも重複が発生することがわかりました。4 つのファイルを含む小さなプログラムを次に示します。
(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
です。誰かが私の質問に答えてくれますか、またはプログラムの間違いを見つけるのを手伝ってくれますか?
ところで、正直なところ、私が取り組んでいる別のプロジェクトでは、動的ライブラリと静的ライブラリでグローバル変数のアドレスが同じであることがわかりました。しかし、そのプロジェクトは大きすぎるため、動作を再現するための小さなプログラムを提供することはできません。
どうもありがとう !