2012-12-26 18 views
6

से फ्री लाइब्रेरी को कॉल कर सकते हैं, हम देख सकते हैं कि हमें DllMain एंट्री पॉइंट फ़ंक्शन में LoadLibrary/FreeLibrary को कॉल नहीं करना चाहिए।क्या हम एमएसडीएन दस्तावेज़ से ExitInstance

एंट्री पॉइंट फ़ंक्शन केवल सरल प्रारंभिकता या समाप्ति कार्यों को निष्पादित करना चाहिए। इसे लोडLibrary या LoadLibraryEx फ़ंक्शन (या कोई फ़ंक्शन जो इन फ़ंक्शंस को कॉल करता है) को कॉल नहीं करना चाहिए, क्योंकि यह DLL लोड ऑर्डर में निर्भरता लूप बना सकता है। सिस्टम के प्रारंभिक कोड को निष्पादित करने से पहले इसका परिणाम डीएलएल का उपयोग किया जा सकता है। इसी तरह, प्रवेश बिंदु समारोह, प्रक्रिया समाप्ति दौरान FreeLibrary समारोह (या एक समारोह है कि FreeLibrary कॉल) फोन नहीं करना चाहिए क्योंकि यह एक DLL में परिणाम कर सकते बाद प्रणाली अपनी समाप्ति कोड निष्पादित किया गया है इस्तेमाल किया जा रहा।

मेरा प्रश्न है: क्या हम ExitInstance() से FreeLibrary को कॉल कर सकते हैं? उदाहरण के लिए: - मुख्य निष्पादन

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 नियमित DLLs गतिशील 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 से जुड़ा हुआ - रेगुलर DLLs , संसाधन

...

मुझे लगता है कि हमें नहीं करना चाहिए, लेकिन CWinApp :: ExitInstance() के प्रत्यारोपण से, हम इसे देख सकते हैं, यह संसाधन डीएलएल को अनलोड करने का भी प्रयास कर रहा था। क्या इसका मतलब है कि हम ExitLntance() में फ्री लाइब्रेरी को कॉल कर सकते हैं?

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

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

मुझे एक दस्तावेज़ भी मिला जो पुष्टि करता है कि Win95 में ExitInstance से FreeLibrary को कॉल करते समय एक बग है।

बग: जोर जब ExitInstance से http://support.microsoft.com/kb/187684

स्थिति AfxFreeLibrary कॉलिंग: माइक्रोसॉफ्ट इस की पुष्टि की है Windows 95 में एक बग होने के लिए हम इस बग शोध कर रहे हैं और यहाँ नई जानकारी पोस्ट करेंगे माइक्रोसॉफ्ट नॉलेज बेस के रूप में यह उपलब्ध हो जाता है।

+0

जब आप ExitInstance() को कॉल करते हैं तो डीएलएल जारी करने का कोई बिंदु नहीं है। जब प्रक्रिया समाप्त हो जाती है तो डीएलएल कुछ मिलीसेकंड बाद में स्वचालित रूप से अनलोड हो जाएगा। –

+0

चूंकि मुख्य निष्पादन योग्य में CWinApp घोषित किया गया है, इसलिए इसके ExitInstance को DllMain से नहीं कहा जाता है (अन्य कारणों से, क्योंकि निष्पादन योग्य में DllMain नहीं है)। सवाल इसलिए मंथन है। –

+0

@ रेमंड कैन, धन्यवाद, मैंने अपने प्रश्न को परिष्कृत किया है कि TestApp.dll गतिशील रूप से एमएफसी से जुड़ा एक नियमित डीएलएल है, इसलिए ExitDstMance में DLL_PROCESS_DETACH संदेश के जवाब में ExitInstance() को कॉल किया गया था। – adshuangjoh

उत्तर

5

वास्तव में ExitInstance DllMain से बुलाया जा रहा हो (के रूप में स्टैक ट्रेस द्वारा की पुष्टि की) तो DllMain के लिए सभी नियमों लोड हो रहा है पर निषेध सहित या रिकर्सिवली अन्य DLLs उतारने लागू होते हैं,। (ध्यान दें कि एक डीएलएल में अपना सीडब्ल्यूएनएप डालना बेहद असामान्य है और एमएफसी के पास इसके साथ अन्य मुद्दे हो सकते हैं, जैसे कि केबी आलेख में उल्लेख किया गया है। यह नहीं कह रहा कि कोई और समस्याएं छिपी नहीं हैं, लेकिन अतिरिक्त नोट जोड़ने सावधानी।)

+2

ऐसा लगता है कि Win8 में फ्री लाइब्रेरी व्यवहार बदल दिया गया है, जो एमएफसी मॉड्यूल स्टेटस को गड़बड़ कर देता है, अगर आप यह देख सकते हैं कि एमएसडीएन फोरम में संबंधित समस्या [यहां] (http://social.msdn.microsoft.com/मंच/en-US/WinForms/धागा/c872ae41-98e7-43ed-92e8-38f1d68bc5ed) – adshuangjoh

संबंधित मुद्दे