मैं सी # प्रोग्रामर के लिए अपनी कार्यक्षमता उपलब्ध कराने के लिए एक एमएफसी एक्सटेंशन DLL (MFCXDLL_2) को लपेट रहा हूं।सी # .NET उपयोगकर्ता नियंत्रण मूल ऐप के अंदर। संसाधन श्रृंखला की समस्याएं
रैपर "सामान्य भाषा रनटाइम समर्थन (/ clr)" के साथ "साझा एमएफसी डीएलएल का उपयोग कर नियमित डीएलएल" है। (मिश्रित मोड)।
एमएफसीएक्सडीएलएल_2 में कक्षाएं उपलब्ध होंगी जो एमएफसीएक्सडीएलएल_3 में सजाए जाएंगी।
जिस परिदृश्य का मैं अनुभव कर रहा हूं वह वह मामला है जहां MFCXDLL_2 का उपयोग किसी मूल अनुप्रयोग में चल रहे सी # .NET उपयोगकर्ता नियंत्रण से किया जाता है।
एक अन्य एमएफसी एक्सटेंशन DLL -MFCXDLL_1- देशी एप्लिकेशन के अंदर भी MFCXDLL_2 का उपयोग करता है और यह कारण परेशानी का कारण बनता है।
जब मैं मूल आवेदन शुरू करता हूं तो यह निश्चित रूप से MFCXDLL_2 को लोड करेगा।
जब मैं .NET उपयोगकर्ता नियंत्रण लोड करता हूं, तो उसी MFCXDLL_2 को http://msdn.microsoft.com/en-us/library/ksa99t88.aspx में सलाह के अनुसार स्पष्ट रूप से लोड किया जाता है, "नियमित डीएलएल में डेटाबेस, ओएलई और सॉकेट एक्सटेंशन डीएलएल का उपयोग करना"।
देशी कोड और .NET उपयोगकर्ता नियंत्रण दोनों एक ही कक्षा के प्रकार को तुरंत चालू करते हैं और उसी विधि को MFCXDLL_2 में कॉल करते हैं।
विधि डेटा को साझा करता है (साझा स्मृति से प्राप्त) और कॉलर को डी-सीरियलाइज्ड डेटा देता है। जब तक मैं .NET उपयोगकर्ता नियंत्रण लोड नहीं करता तब तक यह देशी कोड से बहुत अच्छा काम करता है।
.NET उपयोगकर्ता नियंत्रण लोड करने के बाद, डी-सीरियलाइजिंग मूल कोड से काम करना बंद कर देता है लेकिन .NET उपयोगकर्ता नियंत्रण से कॉल होने पर यह बहुत अच्छा काम करता है।
मैंने मूल अनुप्रयोग के डीबग संस्करण में WinDbg संलग्न किया और अपना परिदृश्य चलाया। डी-सीरियलाइजेशन के दौरान निम्नानुसार WinDbg पाया गया:
"चेतावनी: संग्रह से लोड नहीं हो सकता है। कक्षा परिभाषित नहीं है। कैरचिव अपवाद: badClass। "
मुझे लगता है कि यहां कुछ संसाधन समस्याएं हैं इसलिए मैं एमएफसीएक्सडीएलएल_2 के रिलीज संस्करण को लोड करने वाले देशी एप्लिकेशन का रिलीज़ संस्करण चलाता हूं। फिर मैं .NET उपयोगकर्ता नियंत्रण का डीबग संस्करण लोड करता हूं - जो फिर से मूल अनुप्रयोग में MFCXDLL_2 के डीबग संस्करण को लोड करता है।
तब सबकुछ बढ़िया काम करता है। मूल कोड द्वारा लोड किए गए MFCXDLL_2 का एक रिलीज़ संस्करण और .NET उपयोगकर्ता नियंत्रण द्वारा लोड MFCXDLL_2 का एक डीबग संस्करण - मूल एप्लिकेशन के अंदर चल रहा है।
तो क्या हो रहा है? क्या एमएफसीएक्सडीएलएल को उदाहरण से एक्सेस करना संभव नहीं है एक ही आवेदन में एक ही समय में एक विस्तार डीएलएल और नियमित डीएलएल?
क्या संसाधन श्रृंखला किसी तरह से नष्ट हो गई है? संभावित समाधान क्या हैं?
यहाँ कुछ दिखा कैसे MFCXDLL_2 DLL लोड किया जाता है
कोड जब स्थानीय एप्लिकेशन MFCXDLL_2 DllMain कहा जाता है शुरू होता है:
static AFX_EXTENSION_MODULE MFCXDLL_2 = { NULL, NULL };
static CDynLinkLibrary* gpDynLinkLibrary = NULL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization
AfxInitExtensionModule(MFCXDLL_2, hInstance);
// Insert this DLL into the resource chain
gpDynLinkLibrary = new CDynLinkLibrary(MFCXDLL_2);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Terminate the library before destructors are called
AfxTermExtensionModule(MFCXDLL_2);
}
return 1; // ok
}
है।नेट उपयोगकर्ता नियंत्रण लोड किया जाता है, MFCXDLL_2 DLL फिर से भरी हुई है:
//==============================================================
// Exported DLL initialization to run in context of Regular DLL.
// Must be called in InitInstance
// BOOL CYourRegularDLLApp::InitInstance()
//==============================================================
extern "C" _declspec(dllexport) CDynLinkLibrary* WINAPI InitMFCXDLL_2FromRegularDLL()
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Create a new CDynLinkLibrary for this Regular DLL
return new CDynLinkLibrary(MFCXDLL_2);
}
deserialize कोड MFCXDLL_2 अंदर
CMyClass* pMyclass = NULL; //CObject derived serializeable class
BYTE *pBuf = pGlobalCom->GetBuffer(); //Buffer with serialized CMyClass
int nBufSize = pGlobalCom->GetSize(); //Size of buffer
CMemFile mf;
mf.Attach(pBuf,nBufSize);
CArchive ar(&mf, CArchive::load); //“Warning: Cannot load CMyClass from archive. Class not defined.CArchive exception: badClass.”
ar >> pMyclass; //CArchive exception thrown
ar.Close();
mf.Detach();
छवि DLLs के बीच संबंधों को प्रदर्शित करते हैं।
मैं देख सकता हूं कि सी # रैपर समस्या को हल कैसे करेगा। यह समस्या का समाधान कैसे करता है? मैं लेख http://www.codeguru.com/cpp/cpp/cpp_managed/interop/article.php/c6867 में दिए गए पैटर्न का पालन कर रहा हूं। प्रबंधित और अप्रबंधित दुनिया के बीच वास्तविक पुल मिश्रित मोड डीएलएल है। रैपर केवल उन वर्गों को सजाने के लिए तैयार करता है जिन्हें मैं .NET उपयोगकर्ता नियंत्रण के लिए दिखाना चाहता हूं। – kjella
आप सही हैं। तस्वीर गलत थी। यह निश्चित रूप से "साझा एमएफसी डीएलएल का उपयोग कर नियमित डीएलएल" है जो रैपर है। मैंने अब तस्वीर बदल दी है। MFCXDLL_3 MFCXDLL_2 में कुछ कक्षाओं को सजाने और उपयोगकर्ता नियंत्रण के लिए आवश्यक आवश्यक कार्यक्षमता बनाते हैं। – kjella
कोडगुरु पैटर्न जिसे आप देख रहे हैं 2004 से है। मुझे पूरा यकीन है कि यह अब लागू नहीं होगा (कम से कम नेट 3.5 के बाद)। मैं कोड के साथ दोबारा जांच कर सकता हूं जो मेरे पास दूसरी मशीन पर है और बाद में पोस्ट करेगा। – ChrisBD