2012-12-26 8 views
6

'dan FreeLibrary'i çağırabiliriz MSDN dosyasından, DllMain giriş noktası işlevinde LoadLibrary/FreeLibrary'i çağırmamalıyız.ExitInstance

Giriş noktası işlevi yalnızca basit başlatma veya sonlandırma görevleri gerçekleştirmelidir. LoadLibrary veya LoadLibraryEx işlevini (veya bu işlevleri çağıran bir işlevi) çağırmamalıdır, çünkü bu, DLL yükleme sırasına bağımlılık döngüleri oluşturabilir. Bu, sistem başlatma kodunu çalıştırmadan önce kullanılan bir DLL ile sonuçlanabilir. Benzer şekilde, işleminin sonlandırılması sırasında giriş noktası işlevi FreeLibrary işlevini (veya FreeLibrary'i çağıran bir işlevi) çağırmamalıdır; çünkü bu, sisteminin sonlandırma kodunu yürüttükten sonra kullanılmakta olan bir DLL ile sonuçlanabilir.

Sorum: ExitInstance() 'dan FreeLibrary'i arayabilir miyiz? örneğin: - Ana yürütülebilir

HINSTANCE hDllMFC = LoadLibrary(L"TestApp.dll"); 
if (hDllMFC != NULL) 
{ 
    FreeLibrary(hDllMFC); 
} 

while unload the hDllMFC, the call stack looks like: 

TestApp.dll!CTestAppApp::ExitInstance() Line 42 C++ 
TestApp.dll!InternalDllMain() Line 155 C++ 
TestApp.dll!DllMain() Line 272 C++ 
TestApp.dll!__DllMainCRTStartup() Line 512 C 
TestApp.dll!_DllMainCRTStartup() Line 477 C 
ntdll.dll!LdrpUnloadDll() Unknown 
ntdll.dll!LdrUnloadDll() Unknown 
KernelBase.dll!FreeLibrary() Unknown 
Test.exe!wmain() Line 17 C++ 

TestApp.dll -

Test.exe Normal bir DLL dinamik MFC

CTestApp theApp; 
HINSTANCE hDllResource = NULL; 

BOOL CTestApp::InitInstance() 
{ 
    hDllResource = ::LoadLibrary(L"TestApp_Resource.dll"); 

    return CWinApp::InitInstance(); 
} 

int CTestApp::ExitInstance() 
{ 
    ::FreeLibrary(hDllResource); 

    return CWinApp::ExitInstance(); 
} 

TestApp_Resource.dll bağlantılı - Normal DLL kaynak

...

Sanırım yapmamalıyız, fakat CWinApp :: ExitInstance() 'ın parçalanmasından dolayı, şunu da görebiliyoruz, aynı zamanda kaynak dll'yi boşaltmaya çalışıyordu. Bu ExitIntance() içinde FreeLibrary'i arayabileceğimiz anlamına mı geliyor?

int CWinApp::ExitInstance() 
{ 
    //... 

if (m_hLangResourceDLL != NULL) 
    { 
    ::FreeLibrary(m_hLangResourceDLL); 
    m_hLangResourceDLL = NULL; 
    } 
    //... 
} 

Ben de Win95 ExitInstance dan FreeLibrary'i arama sırasında bir hata olduğunu teyit bir belge bulundu.

Hata: Biz bu hatayı araştırmak olan Microsoft Windows 95'te bir hata olması için onaylamıştır ve burada yeni bilgiler yayınlayacağız: STATUS ExitInstance den http://support.microsoft.com/kb/187684

AfxFreeLibrary çağrılırken İddia Microsoft Bilgi Bankası kullanıma sunulduğunda. (Yığın izleme ile teyit edilmiştir) aslında ExitInstance DllMain'de çağrılan ise

+0

ExitInstance() öğesini çağırdığınızda nokta bırakma DLL'leri yoktur. Süreç sona erdiğinde, DLL birkaç milisaniye sonra otomatik olarak kaldırılır. –

+0

CWinApp ana çalıştırılabilir içinde bildirildiğinden, ExitInstance, DllMain'den (diğer nedenlerden ötürü yürütülebilir dosyalar bir DllMain içermediğinden) çağrılmaz. Bu nedenle soru tartışmalıdır. –

+0

@RaymondChen, teşekkürler, TestApp.dll dosyasının MFC'ye dinamik olarak bağlanmış bir Düzenli DLL olduğu yönündeki soruyu inceledim, bu nedenle ExDitMaliyeti(), InternalDllMain'deki DLL_PROCESS_DETACH mesajına yanıt olarak çağrıldı. – adshuangjoh

cevap

5

sonra DllMain'de için tüm kuralları yükleme yasağı de dahil olmak üzere veya ters diğer DLL boşaltma uygulanır. (CWinApp'in bir DLL'ye yerleştirilmesinin çok sıra dışı olduğunu ve MFC'nin BB makalesinde belirtildiği gibi başka sorunları olabileceğini unutmayın. Daha fazla sorun olduğunu veya gizlenmediğini söylemekten başka bir şey eklemediğini unutmayın. dikkat edin.)

+2

FreeLibrary davranışı Win8, MFC modülü devlet berbat, değiştirildi gibi görünüyor, MSDN forumunda ilgili sorun (http://social.msdn.microsoft.com/Forum/tr/Win/iplik/c872ae41-98e7-43ed-92e8-38f1d68bc5ed) – adshuangjoh