GetSymbol() from wxDynamicLibrary doesn't work well?

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
robal
Experienced Solver
Experienced Solver
Posts: 80
Joined: Thu May 05, 2005 7:46 am

GetSymbol() from wxDynamicLibrary doesn't work well?

Post by robal »

Hi
After big fight with my plugin-driven system based on wxWidgets i found some interesting bug(???). I'm using VC2003 to compile application (wx is used as static linked library). I try to implement plugin system using dll's (for windows) and export classes from it. I implement base class with virtual methods, which is used both in application and dll's (with different linkage specification) and ovewrite that virtual methods in dll. I have C-linkage method in dll to create exported class object (common technique to writting plugins), so i load it using GetSymbol() method from wxDynamicLibrary. Everything works so far, but when i try to call any virtual method from created object in such way there is runtime error - because whole virtual methods table is lost.
I dig in wx code and found, that there is something like:

#elif defined(__WINDOWS__)
symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
#else

and i'm wondering about cast to void* loaded symbol - is it right?
User avatar
Ryan Norton
wxWorld Domination!
wxWorld Domination!
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Re: GetSymbol() from wxDynamicLibrary doesn't work well?

Post by Ryan Norton »

robal wrote:Hi
After big fight with my plugin-driven system based on wxWidgets i found some interesting bug(???). I'm using VC2003 to compile application (wx is used as static linked library). I try to implement plugin system using dll's (for windows) and export classes from it. I implement base class with virtual methods, which is used both in application and dll's (with different linkage specification) and ovewrite that virtual methods in dll. I have C-linkage method in dll to create exported class object (common technique to writting plugins), so i load it using GetSymbol() method from wxDynamicLibrary. Everything works so far, but when i try to call any virtual method from created object in such way there is runtime error - because whole virtual methods table is lost.
I dig in wx code and found, that there is something like:

#elif defined(__WINDOWS__)
symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
#else

and i'm wondering about cast to void* loaded symbol - is it right?
Not sure about casting to void* - but are you calling a function through GetSymbol which creates an instance of the class you want?
krysa
Experienced Solver
Experienced Solver
Posts: 71
Joined: Wed Feb 16, 2005 9:23 pm
Location: Lithuania

Re: GetSymbol() from wxDynamicLibrary doesn't work well?

Post by krysa »

robal wrote:

Code: Select all

#elif defined(__WINDOWS__)
    symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() );
#else
and i'm wondering about cast to void* loaded symbol - is it right?
GetProcAddress returns address of the exported symbol, in the terms of C language - that would be a pointer. So casting this to void* is ok.
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
robal
Experienced Solver
Experienced Solver
Posts: 80
Joined: Thu May 05, 2005 7:46 am

Post by robal »

> GetProcAddress returns address of the exported symbol, in the terms of C language - that would be a pointer. So casting this to void* is ok.

Maybe in therms of C language is OK, but the matter is, that i need C++ here. So, when you have one class with pure virtual methods and second one which inherits from it and overwrites virtual methods there is a problem. Object is created, but virtual methods table is lost (because of casting to void*) and whole mechanism doesn't work.
I tried to do it without casting to void (using GetProcAddress) and it works OK, so i think that such casting here is not right way in this case.
krysa
Experienced Solver
Experienced Solver
Posts: 71
Joined: Wed Feb 16, 2005 9:23 pm
Location: Lithuania

Post by krysa »

robal wrote:Maybe in therms of C language is OK, but the matter is, that i need C++ here. So, when you have one class with pure virtual methods and second one which inherits from it and overwrites virtual methods there is a problem. Object is created, but virtual methods table is lost (because of casting to void*) and whole mechanism doesn't work.
I tried to do it without casting to void (using GetProcAddress) and it works OK, so i think that such casting here is not right way in this case.
As far as i know, GetProcAddress RETURNS void*, any other way would be funny, because GetProcAddress doesn't know what type of resource you are accessing. I am pretty sure you are missing something in your application. Do you cast it to a right class before you use it? Can you post some code?
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
User avatar
Ryan Norton
wxWorld Domination!
wxWorld Domination!
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Post by Ryan Norton »

krysa wrote:
robal wrote:Maybe in therms of C language is OK, but the matter is, that i need C++ here. So, when you have one class with pure virtual methods and second one which inherits from it and overwrites virtual methods there is a problem. Object is created, but virtual methods table is lost (because of casting to void*) and whole mechanism doesn't work.
I tried to do it without casting to void (using GetProcAddress) and it works OK, so i think that such casting here is not right way in this case.
As far as i know, GetProcAddress RETURNS void*, any other way would be funny, because GetProcAddress doesn't know what type of resource you are accessing. I am pretty sure you are missing something in your application. Do you cast it to a right class before you use it? Can you post some code?
It returns a FARPROC, even in WIN16 -

Code: Select all

typedef INT_PTR (FAR WINAPI *FARPROC)();
AFAIK casting from and to from a pointer to function to a void* is technically illegal - see the c++ faq -

http://www.parashift.com/c++-faq-lite/p ... l#faq-33.8
krysa
Experienced Solver
Experienced Solver
Posts: 71
Joined: Wed Feb 16, 2005 9:23 pm
Location: Lithuania

Post by krysa »

Ryan Norton wrote:It returns a FARPROC, even in WIN16 -

Code: Select all

typedef INT_PTR (FAR WINAPI *FARPROC)();
AFAIK casting from and to from a pointer to function to a void* is technically illegal - see the c++ faq -
http://www.parashift.com/c++-faq-lite/p ... l#faq-33.8
I was wrong. I always thought FARPROC is just another winapi way to write void*. Could you make the wx minimal sample that fails on this?
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
robal
Experienced Solver
Experienced Solver
Posts: 80
Joined: Thu May 05, 2005 7:46 am

Post by robal »

I could provide my sample, which causes serious problems with virtual methods table. Lets assume, that you have code in dll:

Code: Select all

class __declspec( dllexport ) CBaseClass
{
    // ...
    virtual Fun() = 0;
};

class __declspec( dllexport ) CClass : public CBaseClass
{
    // ...
    virtual Fun() {}
};

CBaseClass* CreateClass() { return new CClass; }

// ----------------------------------------
// in application code:
// ----------------------------------------

CBaseClass*    pMyClass;

CBaseClass* (*pCreateClass)() = (CBaseClass*(*)()) library.GetSymbol( "CreateClass" );

pMyClass = pCreateClass();

// and here is the problem. Object is created, but virtual methods doesn't // exist.

// ------------------
// this code works OK (pure Windows API):

CBaseClass*    pMyClass;

HINSTANCE	hInst = LoadLibrary( "some path" );
CBaseClass* (*pCreateClass)() = (CBaseClass*(*)()) GetProcAddress( hInst, "CreateClass" );

pMyClass = pCreateClass();

// and object works.
So, this is windows specific case or casting to void* is really not good way to map methods from dll or other dynamic libraries???
User avatar
Ryan Norton
wxWorld Domination!
wxWorld Domination!
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Post by Ryan Norton »

robal wrote: // ----------------------------------------
// in application code:
// ----------------------------------------

CBaseClass* pMyClass;

CBaseClass* (*pCreateClass)() = (CBaseClass*(*)()) library.GetSymbol( "CreateClass" );

pMyClass = pCreateClass();

// and here is the problem. Object is created, but virtual methods doesn't // exist.
Out of curiousity, is your library created like

Code: Select all

wxDynamicLibrary library(wxT("my.dll"));
?
robal
Experienced Solver
Experienced Solver
Posts: 80
Joined: Thu May 05, 2005 7:46 am

Post by robal »

// in details...

wxDynamicLibrary library;

if( true == library.Load( wxT( PATH ) ) )
{
if( true == library.IsLoaded() )
{
pCreateClass = (CBaseClass*(*)()) library.GetSymbol( "CreateClass" )
}
}
Post Reply