Page 1 of 1

Access violation using wxDynamicLibrary

Posted: Fri Jan 08, 2010 11:02 pm
by Dark_Phoenix
I have finally been able to successfully create and load a DLL using wxWidgets. I created a simple app using a lot of global variables to load and unload the DLL like this

Code: Select all

const wxString g_FunctionRegister    = wxT("RegisterPlugin");
const wxString g_FunctionUnregister  = wxT("UnregisterPlugin");
IPlugin *g_pPlugin                   = NULL;
wxDynamicLibrary  LibLoader;
DLLFunctionPtr pFuncRegisterPlugin   = NULL;
DLLFunctionPtr pFuncUnregisterPlugin = NULL;

void CMainFrame::LoadPlugin(const wxString &Filename)
{
    if (!LibLoader.Load(Filename, wxDL_NOW) )
    {
        wxMessageBox(wxT("Could not load Plugin"), wxT("Error"), wxOK, this);
        return;
    }
    if(LibLoader.IsLoaded() )
    {
        if(LibLoader.HasSymbol(g_FunctionRegister) && LibLoader.HasSymbol(g_FunctionUnregister) )
        {
            pFuncRegisterPlugin = (DLLFunctionPtr)(LibLoader.GetSymbol(g_FunctionRegister) );
            pFuncUnregisterPlugin = (DLLFunctionPtr)(LibLoader.GetSymbol(g_FunctionUnregister) );
            if(pFuncRegisterPlugin)
            {
                if (pFuncRegisterPlugin(&g_pPlugin) )
                {
                    g_pPlugin->InitPlugin(this);
                }
            }
            else
            {
                wxMessageBox(wxT("GetSymbol returned NULL"), wxT("Error"), wxOK, this);
            }
        }
        else
        {
            wxMessageBox(wxT("HasSymbol returned NULL"), wxT("Error"), wxOK, this);
        }
    }
}

void CMainFrame::UnloadAllPlugins()
{
    if (g_pPlugin)
    {
        if(pFuncUnregisterPlugin)
        {
            pFuncUnregisterPlugin(&(g_pPlugin) );
        }
    }
}
Now I am tring to do away with the globals and set it up so that I can load multiple DLLs using wxDynamicLibrary::Detach()... So I changed a few lines

Code: Select all

wxDllType g_LibHandle = 0;

void CMainFrame::LoadPlugin(const wxString &Filename)
{
...
                if (pFuncRegisterPlugin(&g_pPlugin) )
                {
                    g_LibHandle = LibLoader.Detach();
                    g_pPlugin->InitPlugin(this);
                }
...
}

void CMainFrame::UnloadAllPlugins()
{
    if (g_pPlugin)
    {
        if(pFuncUnregisterPlugin)
        {
            pFuncUnregisterPlugin(&(g_pPlugin) );
        }
        wxDynamicLibrary::Unload(g_LibHandle);
    }
}
Now I am getting an access violation as the app is shutting down.

I can only guess that it has something to do with how I am using the Detach member function, but I am not quite getting it.

Can anyone tell me what I am doing wrong?

Posted: Sat Jan 09, 2010 12:04 pm
by Dark_Phoenix
OK, so I figured out that if I dynamically create a wxDynamicLibrary object

Code: Select all

wxDynamicLibrary* LibLoader = new wxDynamicLibrary;
then everything works fine as long as I don't explicitly delete LibLoader. But when I call

Code: Select all

delete LibLoader;
I get the access violation again. But since I created LibLoader on the heap I have to explicitly delete it or I will end up with a memory leak... right?

What is going on here?

Posted: Sat Jan 09, 2010 4:04 pm
by Auria
Well, at which point do you delete it? You must only delete it after you're done with it, of course

Posted: Sat Jan 09, 2010 8:58 pm
by Dark_Phoenix
It is the last thing that is called prior to wxWindow::Destroy()

Posted: Sun Jan 10, 2010 1:40 am
by JimFairway
Hi,

There's no need to delete it according to the documentation here:
http://docs.wxwidgets.org/stable/wx_wxd ... brary.html

and here which is what Unload calls for windows
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

The DLL is ref counted and when it gets to 0, the memory is released, Unload is called in the destructor of wxDynamicLibrary.

Hope that helps,

Jim

Posted: Sun Jan 10, 2010 11:48 am
by Dark_Phoenix
Unload is called in the destructor of wxDynamicLibrary
But if wxDynamicLibrary was created with 'new' then wouldn't the destructor not be called untill 'delete' was called?

Posted: Sun Jan 10, 2010 3:16 pm
by Dark_Phoenix
Seems my problem was not with my app after all, but with the DLL that I created... I found this after some googling and thought that since my DLL was adding a menu item to the app's menubar then maybe the DLL needed to delete the menu as well... That seems to have done the trick