混在DLLにおける問題

「.NET Framework」と「Win32API」を混ぜて作成した、Win32形式のDLLを混在DLLと呼びます。

Visual C++ .NET 2003で作成できますが、単純にエントリポイント(DLLMain)を実装する事は禁止されています。何が起こるかというと循環参照による無限ループの可能性です。なお、この問題はVisual C++ 2005で若干改善されました。



そもそもDLLのエントリポイント関数には暗黙のルールが存在します。DLLは自分の初期化にDLLMainを利用しているためです。特にはまりそうな禁止事項は以下のとおり。

  • Kernel32.DLL以外のインポート関数の利用
  • LoadLibraryやFreeLibraryの利用
  • レジストリ関数の利用(※1)

この注意事項は毎回、「Advanced Windows」やMSDN等を参照して確認しています。

詳しい話はKB814472を参照するとして、理解できない方はDLLを止めてEXEとして作成してください。



KB814472 – [PRB] C++ マネージ拡張の DLL プロジェクトをビルドするときにリンカの警告が表示される

[MSDN] – 混在モード DLL 読み込み時の問題

[MSDN] – How To: Remove Dependency on _vcclrit.h



※1 これは何故駄目なのでしょう。間接的にLoadLibraryを呼び出すと推測。(←それ以前の問題のようです)



(05/12/15) 一部加筆。Visual C++ 2005にてこの問題が一部解決した。
(06/03/12) レジストリ関数はAdvapi32.libらしい・・・。しかし、Kernel32.dllの関数は常に安全と書いてあっても、そうでない=常に危険とも書かれていないのが悩みどころ。

Leave a Reply

2 コメント - "混在DLLにおける問題"

更新通知を受け取る »
avatar
並び替え:   新しい順 | 古い順 | 最も評価の多い
通りすがり
ゲスト

レジストリ関数(Reg~系)はadvapi32.dllですよ。
だから最初の「kernel32.dll以外」に当てはまっているからと言えませんか。

konuma
ゲスト

コメントありがとうございます。確認したら確かにそのようです。
# 結局Kernel32.dllの関数でないものを全て使うなということでしょうか?
初期化タイミングとして「PROCESS_ATTACH」系は使いやすいんですが、フラグを覚えておくだけしか出来ないのが残念です。
そもそもnewすら出来ないのが更に嫌な感じですけど、こちらはGetProcessHeapで代用してます。

wpDiscuz