I need some clarification regarding the runtime / heap problems when deleting an object that was created in the DLL. I need some insight before I come to my questions ...
In my project, the DLL (indicated by its name) returns a new Grabber object. In an earlier version of my code, the DLL exported this function:
extern "C" __declspec(dllexport) Grabber* CreateGrabber(string settings) { return new SomeSpecificGrabber(settings); }
In EXE, I used a static function like this to create a new Grabber object:
static Grabber* createGrabberObject(const std::string& grabberType, const std::string& grabberSettings) { FARPROC hProc = 0;
In EXE, the lifetime of a Grabber object is controlled by a smart pointer:
shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"));
All this worked fine as long as I compiled the EXE and DLL using the /MDd (VC ++ 2010), which means that the EXE and DLL used the same heap.
Now I want to compile my solution using the /MTd . With this, I got a runtime statement of type _CrtIsValidHeapPointer for the settings string object that I passed to the DLL. This makes sense because the DLL is trying to remove the string object that was created in the EXE. And they no longer use the same heap.
I ran into this problem by slightly changing the exported DLL function ( const char* instead of string ):
extern "C" __declspec(dllexport) Grabber* CreateGrabber(const char* settings) { return new SomeSpecificGrabber(settings); }
And in createGrabberObject I pass grabberSettings.c_str() instead of grabberSettings DLL function.
Now everything is working fine. But now my first question appears. Why don't I get the _CrtIsValidHeapPointer statement when myGrabberObj is removed? The object was created from a DLL, but removed from the EXE (using a smart pointer). Why don't I have the same problem here as with the string object above?
I think the clean solution would be that the DLL also exports such a function:
extern "C" __declspec(dllexport) void DeleteGrabber(Grabber* grabber) { delete grabber; }
Then I would also have a static function in the EXE that calls DeleteGrabber in the DLL:
static void deleteGrabberObject(const std::string& grabberType, Grabber* grabber) { FARPROC hProc = 0;
This static function can be automatically called by a smart pointer:
shared_ptr<Grabber> myGrabberObj = shared_ptr<Grabber>(createGrabberObject("SomeGrabber.DLL", "Settings"), boost::bind(deleteGrabberObject, "SomeGrabber.DLL", _1));
This also works. But here is my second question : the static functions createGrabberObject and deleteGrabberObject load the DLL. Does this mean that two different heaps are created because two instances of the DLL are loading (then this solution would not solve my problem at all)? Or are these two static functions using the same heap?
Hope someone can explain what is going on here ...