• ベストアンサー

DLLはアドレスを共有する?

 CでWindowsプログラミングの勉強をしています.そこでDLLについての質問なのですが,ある本で「DLLは複数のプログラムが共有し,ひとつのDLLはひとつしかメモリ上に配置されない」という文章を読みました.プログラムはDLLの配置されてあるアドレスを元に,DLL内の関数を実行するのだと考えれば納得はいきましたが,よく考えたらおかしいと思いました.  それは「変数,関数」の取り扱いはどうなるのか,ということです.C言語で物理メモリアドレスを見る方法がわからないので何とも言えませんが,試しに,DLL内に次のような関数MyFunctionを用意し,このDLLを取り込むプログラムを同時に2つ走らせ,MyFunctionを何度も呼んでDll1_Variableの値を増加させていきました. LIBSPEC int MyFunction(LPCWSTR str) { static int Dll1_Variable=0; Dll1_Variable++; _tprintf(_T("%d\n"),Dll1_Variable); return 0; }  もしDLLが共有されているのならば,Dll1_Variableの値は2つのプログラムから同時に更新されると思うのですが,実際には2つのプログラム上でまったく独立(つまり各プログラムごとに1,2,3,...というように)増加していきました.こうなるとDLLって本当に共有されているのかという,不信感が出てきてしまいます.  なんだか重大な勘違いをしている気がしてなりませんが,上記のプログラムがなぜ独立に変数が増加していくのか,「DLLが共有される」というのは実際にはどういう仕組みになっているのか,ご存知の方がいらっしゃったらご教授ください.わかりにくい質問ですみません.よろしくお願いします.

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

Win32(要するにNTとか、95以降の奴)ではコードの共有をどのようにしていたか(していないか)は ちょっと忘れてしまいましたが、データ部分については、特に指定しない限りは プロセスごとに独立した空間が割り当てられます。 ですので質問の例にあるように、カウンタは独立して増えることになります。 DLL 内のデータをアプリケーションまたはほかの DLL と共有する方法 http://msdn.microsoft.com/ja-jp/library/h90dkhs0.aspx 参考までに、Win16(Windows 3.1とか)の場合は、 プログラムコードはまるっきり共有されますが、 データ部分はこれもプロセスごとになります。 #コード→CSレジスタで示す領域 #データ→DSレジスタで示す領域

noname#129397
質問者

お礼

なるほど,コードの共有は行ってもデータについては個々に持っているということですね.よくわかりました.ありがとうございます.

その他の回答 (2)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

>スレッドの場合も個々にデータを保持しているのでしょうか. これは、特に指定しない限りは、同じプロセスに属するスレッドであれば 全く同じデータを共有します。 なので、 > スレッドの場合は何か特別な事情が生じてくることはあるのでしょうか. まさしくこのとおりです。 スレッド ローカル ストレージ (TLS: Thread Local Storage) http://msdn.microsoft.com/ja-jp/library/6yh4a9k1.aspx

noname#129397
質問者

お礼

なるほど,スレッドの場合は気をつけなければならないということですね.よく理解できました.ありがとうございます.

  • wolf03
  • ベストアンサー率22% (241/1086)
回答No.2

プログラムがロードされる領域と変数が使う領域は別物だからです。

noname#129397
質問者

お礼

そうですよね.単純な事実にまったく気がつきませんでした. ところで,これに共有に関してさらに疑問に思ったこととして,マルチスレッドの状況で複数のスレッドがDLLを共有するとどうなるのでしょう?スレッドは確かメモリ空間を共有するという話を聞きましたが,スレッドの場合も個々にデータを保持しているのでしょうか. 「スレッドセーフ」という言葉もあることですし,スレッドの場合は何か特別な事情が生じてくることはあるのでしょうか.

関連するQ&A

専門家に質問してみよう