2012-06-28 57 views
10

私はネイティブDLLとやりとりするWebサービスで作業しています.LoadLibrary/GetModuleHandle/FreeLIbraryとGetProcAddressを使用すると、DLLが非常に安定していないため、動的にロード/アンロードされます。LoadLibrary、FreeLibrary、およびGetModuleHandle Win32関数はスレッドセーフですか?

public class NativeMethods 
{ 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern IntPtr LoadLibrary(string libname); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern IntPtr GetModuleHandle(string libname); 

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public static extern bool FreeLibrary(IntPtr hModule); 

    [DllImport("kernel32.dll", CharSet = CharSet.Ansi)] 
    public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); 
} 

私はw3wp.exeのプロセスがoccationally重い負荷の下でクラッシュし、私はそれをデバッグしようとしたとき、デバッガは、多くの場合、私のNativeMethods.GetModuleHandle()関数呼び出しで停止していることに気付きました。

GetModuleHandleはスレッドセーフではないという証拠を見つけることができなかったので、これらのkernel32.dll関数をマルチスレッド.NETアプリケーションとやりとりするときに誰もが似たような経験を得ているのだろうか?イゴールTandetnik(マイクロソフトMVP)によると、オスカー

+1

LoadLibraryとFreeLibraryはDLLロードリストに対して相対的にスレッドセーフでなければなりません。理論的にはGetModuleHandleを使うべきですが、おそらくそのメソッドを使用する代わりにLoadLibrary/FreeLibraryペアを使用しますあなたがそれを使用している間はメモリから消えることはありません。 – tyranid

答えて

6

スレッドセーフではないGDI関数を除いて。 HWNDおよび/またはHDCを取るものは、HWNDまたはHDCが作成された同じスレッド(SendMessage,PostMessageなどの例外は例外です)で呼び出される必要があります。 HBITMAP s、HICONなどはスレッド間で渡すことができますが、一度に1つのスレッドで操作する必要があります。

GDIやウィンドウ管理を扱わない他のほとんどの関数は、実際にはスレッドセーフです。

これは、LoadLibrary,GetModuleHandle,FreeLibraryおよびGetProcAddressを含む必要があります。

ただし、FreeLibraryは、DllMainから呼び出さないでください。

私は、これらの機能をマルチスレッド環境で長時間問題なく使用していることを追加することもできます。

+0

https://mvp.support.microsoft.com/profile=b3eb0170-44f2-4819-b048-8616caa4d107/http://social.msdn.microsoft.com/profile/igor%20tandetnik/?ws=usercard-mini(これが正しい人なら)MSのために働かない?彼はMVPです... – Anders

+0

前のコメントを反映するように変更されました –

+0

'LoadLibrary'はモジュールの参照カウントをインクリメントしますが、' GetModuleHandle'はモジュールの参照カウントをインクリメントしません。悲しいことに、これは 'GetModuleHandle'をスレッドセーフにしません。詳細については、**備考**セクションを参照してください。https://msdn.microsoft.com/en-us/library/windows/desktop/ms683199(v=vs.85).aspx重要な注釈** **たとえば、スレッドがモジュールハンドルを取得するが、ハンドルを使用する前に、2番目のスレッドがモジュールを解放することを示します。 .... ** –

関連する問題