Access violation using wxDynamicLibrary Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Access violation using wxDynamicLibrary

Post by Dark_Phoenix » Fri Jan 08, 2010 11:02 pm

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?

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Sat Jan 09, 2010 12:04 pm

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?

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Sat Jan 09, 2010 4:04 pm

Well, at which point do you delete it? You must only delete it after you're done with it, of course
"Keyboard not detected. Press F1 to continue"
-- Windows

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Sat Jan 09, 2010 8:58 pm

It is the last thing that is called prior to wxWindow::Destroy()

JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Post by JimFairway » Sun Jan 10, 2010 1:40 am

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
OS: Vista SP1, wxWidgets 2.8.7.

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Sun Jan 10, 2010 11:48 am

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?

Dark_Phoenix
Knows some wx things
Knows some wx things
Posts: 48
Joined: Sat Jul 04, 2009 2:27 pm
Location: Houston, TX

Post by Dark_Phoenix » Sun Jan 10, 2010 3:16 pm

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

Post Reply