自作したDLLを同じプロセスで LoadLibrary で複数回
読み込みをおこなってみたら、DLL内のグローバル変数の値が
同じになっていました。
この値を別のものとして扱うことはできるのでしょうか?
俺の知っている知識では出来ないよ。
複数必要なものならグローバル変数は使うなってことだな。
DLL内で定義されるグローバル変数といえど、LoadLibraryした親プロセスのメモリ空間
に展開されるので、実行時には呼び出し側プログラム内で定義したグローバル変数と同
じような状態だと思います。
複数回読み込みをおこなっていたら・・・とあるので、2回目以降呼び出したときにグロ
ーバル変数を初期化しておきたいのかなと想像しましたが・・・。
その目的であれば、グローバル変数のリセット用関数を作って明示的にコールするなど
すれば対応できるかと思います。
読み込みから作業終了までが個別に行われるなら
きちんとアンロードすればいい。
マルチスレッドで、個々のスレッドごとにDLLを読み込む・・・
みたいに、複数方面からグローバル変数を弄っちゃうっというのなら
wclrp ( 'o')さんの言うようにグローバルであることがまず間違い
DLL側が変更不能なら、読み込む前にDLLをファイルコピーして
別名のDLLとして読み込むって方法があるそうだが
試したこと無いので・・・
そもそも LoadLibrary を複数回やっても、DLL のインスタンスは1つしかできないけ
ど…
> そもそも LoadLibrary を複数回やっても、DLL のインスタンスは1つしかできないけど…
多分これが一番ダイレクトな回答かと。
複数回LoadLibraryをしても最初のインスタンスを返しているだけで
何個も読み込んでいるわけでは無いと思いますよ。
つまり、インスタンスを分けたくて複数回読み込むこと自体が間違いと言う事になります。
ちと補足
>自作したDLLを同じプロセスで LoadLibrary で複数回
なので、1つのプロセスから何度LoadLibrary()しても、
DLLのグローバル変数および静的変数のインスタンス
は1つしかできません。回答者みなさんのおっしゃる
通りです。
尚、複数のプロセスから各々がLoadLibrary()した場合は、
プロセス毎に別々のグローバル変数および静的変数
のインスタンスが作成されるので、全く別のものと
なります。
んで、結局何がしたいのでしょう。それによっては
別の回答をしてもらえるかもしれません。
24島さんが何をしたいかによって回答が変わります。
たぶん、そのことが分かっていないですよね?
ここまでのみなさんの回答バラバラですが、状況次第でみなさんの回答は全部
正解なんです。
もし、同一プロセスから LoadLibrary() を呼ぶたびに、DLL内のグローバル変数
を別物として扱いたいなら無理。
理由は aetos さんのおっしゃっているとおり。
最初の LoadLibrary() で DLL がロードされ、参照カウントが1になります。
次の LoadLibrary() ではロード済みなので、参照カウントが2になるだけです。
以降、同様に参照カウントが増えるだけです。
次に、FreeLibrary() を呼び出すと、参照カウントが減ります。
FreeLibrary() を呼び出すたびに参照カウントが減っていき、0になるとDLLが
アンロードされます。
ただ、参照カウントは、プロセス毎に持ちますので、プロセスが変われば別物
となります。これは 仲澤@失業者 さんのおっしゃる通り。
さらに、同一プロセスからでも、ロードし直されれば再初期化が走ります。
参照カウントが 1 <-> 0 の繰り返しになるような場合ですね。
この場合は、グローバル変数の値はきちんと初期化されます。
(例) int nTest = 0;
この nTest が DLL内のグローバル変数 なら、参照カウントが1になるたびに
0に初期化されます。
これが ryoさんの話です。
なんとなく伝わったかな?
ありがとうございます。
複数必要な場合は、DLLを別の名称に変更してから
実行するようにします。
勉強になりました。
斬新な解決方法ですね・・・。