destroying classes from an external .dll file

Started by
5 comments, last by McZ 19 years, 7 months ago
I have an abstract class called CShaderBase and inside my CRenderSystem I have a std::list<CShaderBase*> wich will hold pointers to all valid shaders the engine has loaded from an external plugin ( e.g. my OpenGL plugin ) the problem is when I destroy the CRenderSystem class it crashes, I guess this is becouse it tries to delete the shaders in the shader list. if I remove the line where I retrive the shaders from the .dll and have an empty list it doesn't crash and the plugin destroy function deletes the shaders properly. I retrive more classes than the shaders from the plugin and all other stuff works, but not the shaders, I guess it is becouse they are in a std::list and the others are not. I tried to create a simple ShaderPointer class which has a CShaderBase pointer as member and when it is deleted it will just set that member to 0 and not delete it but that doesn't work.
Advertisement
The problem could be a result of the objects being allocated in the DLL and deleted in the application, but there are many other possibilities. Try stepping through it with a debugger and determining which line causes the crash (for example, are you sure it's the deallocation and not the CShaderBase destructor?).

And as always, with out some code we can only guess.....
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
the CShaderBase destructor is empty nothing is done there..

I know it has something to do with that I allocate the memory inside the plugin.dll file and then somthing tries to destroy that inside the application which I have told the app NOT to do, I have tried some type of smartpointers wich will only release the pointer and not destroy it, if I remove the std::list<..> and replace it with a single pointer to CShaderBase item and then I recive only one item from my plugin.dll file then everything works perfect.
Link to the * DLL runtime libraries to fix the problem, like Multithreaded DLL rather than just Multithreaded. However this isn't the best solution, it is just covering up the problem. You should probably use something like com's Release(), but it doesn't have to be reference counting. It could just be:
class CShaderBase{   ...public:   virtual void Delete() = 0;};// OpenGL DLL:class COpenGLShader{   void Delete() { delete this; }};

That will delete from the correct heap.
Quote:Original post by Kibble
Link to the * DLL runtime libraries to fix the problem, like Multithreaded DLL rather than just Multithreaded. However this isn't the best solution, it is just covering up the problem. You should probably use something like com's Release(), but it doesn't have to be reference counting. It could just be:
class CShaderBase{   ...public:   virtual void Delete() = 0;};// OpenGL DLL:class COpenGLShader{   void Delete() { delete this; }};

That will delete from the correct heap.


I have tried that... it still doesn't work as long as I have the pointer to the class inside a std::list<> container.. if I have only one pointer it works.

e.g.

This line doesn't work:
std::list<CShaderBase*> Shaders;

but if I replace that line with this it does
CShaderBase *Shader;

the retrive code looks like this at the moment

DLL_API CShaderBase *getShader(void)
{
MyShader = new CTestShader; // this creates the shader in the .dll

return MyShader;
}

// this is called when engine is shutting down
DLL_API void ShutdownPlugin(void)
{
delete MyShader;
}
You're not passing your std::list between the DLL and the app are you? Passing non-const STL containers over a DLL boundary is just asking for trouble.
You cannot add or remove objects to/from a STL container in both the DLL and the exe, you'll need some kind of accessors to do that.

Aside from that, I'm out of ideas about whats wrong.
can I have a list in the .dll file which the .exe file can retrive using a function and then get the stuff from that list into it's own list?

e.g.

DLL_API std::list<..> *GetShaders(void)
{
// Add a lot of shaders
dllshaderlist.push_back( myshader );
...

return &dllshaderlist
}

and then when I retrive the stuff I do this:

std::list<..> *dll_list = GetShaders();

for( it .... )
{
exelist.push_back( (*it) );
}

dll_list = 0;

btw, how/where do I write in the const keyword on the function to make sure that it will return a const std::list<>?

This topic is closed to new replies.

Advertisement