में बनाई गई ऑब्जेक्ट को हटाने से मुझे डीएलएल में बनाई गई ऑब्जेक्ट को हटाते समय रनटाइम/हीप समस्याओं के बारे में कुछ स्पष्टीकरण चाहिए। मेरे प्रश्नों पर आने से पहले इसे कुछ परिचय की जरूरत है ...एक डीएलएल
मेरी परियोजना में एक डीएलएल (जो इसके नाम से निर्दिष्ट है) एक नया ग्रैबर ऑब्जेक्ट देता है। मेरी कोड के पिछले संस्करण में, DLL इस तरह एक समारोह का निर्यात:
extern "C"
__declspec(dllexport) Grabber* CreateGrabber(string settings)
{
return new SomeSpecificGrabber(settings);
}
EXE में मैं एक नया धरनेवाला वस्तु बनाने के लिए इस तरह एक स्थिर समारोह का प्रयोग किया:
static Grabber* createGrabberObject(const std::string& grabberType, const std::string& grabberSettings)
{
FARPROC hProc = 0;
// load dll with the name of grabberType
HMODULE hDLL = LoadLibrary(grabberType.c_str());
// get address for CreateGrabber function
hProc = GetProcAddress(hDLL, "CreateGrabber");
// instantiate a function pointer of our type and typecast the address
// of the CreateGrabber function to this type
CreateGrabberFunctionType CreateGrabberFunction = (CreateGrabberFunctionType)hProc;
// call CreateGrabber in DLL to get a Grabber object
return CreateGrabberFunction(grabberSettings);
}
EXE में वह पंजे वस्तु के जीवनकाल एक स्मार्ट सूचक द्वारा किया जाता है:
shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"));
यह सब जब तक मैं EXE और /MDd
सेटिंग (वीसी ++ 2010) के साथ DLL संकलित ठीक काम किया, whi सी का मतलब है कि ईईई और डीएलएल ने एक ही ढेर का इस्तेमाल किया था।
अब मैं /MTd
सेटिंग के साथ अपना समाधान संकलित करना चाहता हूं। इसके साथ मुझे डीएलएल में पारित सेटिंग्स स्ट्रिंग ऑब्जेक्ट के लिए _CrtIsValidHeapPointer
प्रकार का रनटाइम assert मिला। यह समझ में आता है क्योंकि डीएलएल एक स्ट्रिंग ऑब्जेक्ट को हटाने की कोशिश करता है जो EXE में बनाया गया था। और वे अब एक ही ढेर का उपयोग नहीं करते हैं।
मैं निर्यात DLL समारोह एक छोटा सा (string
की const char*
बजाय) बदल कर इस समस्या को हल मिल गया:
extern "C"
__declspec(dllexport) Grabber* CreateGrabber(const char* settings)
{
return new SomeSpecificGrabber(settings);
}
और createGrabberObject
में मैं DLL कार्य करने के लिए grabberSettings.c_str()
बजाय grabberSettings
गुजरती हैं।
अब सब कुछ ठीक काम करता है। लेकिन अब मेरा पहला प्रश्न आता है: हटाए जाने पर मुझे _CrtIsValidHeapPointer
दावा क्यों नहीं मिलता है? ऑब्जेक्ट डीएलएल के भीतर से बनाया गया था लेकिन EXE (स्मार्ट पॉइंटर द्वारा) से हटा दिया गया है। मेरे ऊपर उपरोक्त स्ट्रिंग ऑब्जेक्ट के समान समस्या क्यों नहीं है?
मुझे लगता है कि एक साफ समाधान हो सकता है कि DLL भी इस तरह एक समारोह का निर्यात करता है:
static void deleteGrabberObject(const std::string& grabberType, Grabber* grabber)
{
FARPROC hProc = 0;
// load dll with the name of grabberType
HMODULE hDLL = LoadLibrary(grabberType.c_str());
// get address for DeleteGrabber function
hProc = GetProcAddress(hDLL, "DeleteGrabber");
// instantiate a function pointer of our type and typecast the address
// of the DeleteGrabber function to this type
DeleteGrabberFunctionType DeleteGrabberFunction = (DeleteGrabberFunctionType)hProc;
// call DeleteGrabber in DLL
DeleteGrabberFunction(grabber);
}
:
extern "C"
__declspec(dllexport) void DeleteGrabber(Grabber* grabber)
{
delete grabber;
}
तो मैं भी मेरी EXE जो एक DLL में DeleteGrabber कॉल में एक स्थिर समारोह के लिए होता है
यह स्थिर समारोह फिर स्वचालित रूप से स्मार्ट सूचक द्वारा कहा जा सकता है:
shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"),
boost::bind(deleteGrabberObject, "SomeGrabber.DLL", _1));
यह भी काम करता है। लेकिन यहां मेरा दूसरा प्रश्न आता है: स्थिर कार्य createGrabberObject
और deleteGrabberObject
दोनों डीएलएल लोड करते हैं। क्या इसका मतलब यह है कि दो अलग-अलग ढेर बनाए जाते हैं क्योंकि डीएलएल के दो उदाहरण लोड होते हैं (फिर यह समाधान मेरी समस्या को हल नहीं करेगा)? या ये दो स्थिर कार्य एक ही ढेर का उपयोग करते हैं?
मुझे आशा है कि कोई यह बता सकता है कि यहां क्या हो रहा है ...
धन्यवाद! यह वास्तव में तेज़ था! –