GetSymbol() from wxDynamicLibrary doesn't work well?
GetSymbol() from wxDynamicLibrary doesn't work well?
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?
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?
- Ryan Norton
- wxWorld Domination!
- Posts: 1319
- Joined: Mon Aug 30, 2004 6:01 pm
Re: GetSymbol() from wxDynamicLibrary doesn't work well?
Not sure about casting to void* - but are you calling a function through GetSymbol which creates an instance of the class you want?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?
Re: GetSymbol() from wxDynamicLibrary doesn't work well?
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.robal wrote:and i'm wondering about cast to void* loaded symbol - is it right?Code: Select all
#elif defined(__WINDOWS__) symbol = (void*) ::GetProcAddress( m_handle, name.mb_str() ); #else
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
> 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.
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?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.
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
- Ryan Norton
- wxWorld Domination!
- Posts: 1319
- Joined: Mon Aug 30, 2004 6:01 pm
It returns a FARPROC, even in WIN16 -krysa wrote: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?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.
Code: Select all
typedef INT_PTR (FAR WINAPI *FARPROC)();
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?Ryan Norton wrote:It returns a FARPROC, even in WIN16 -AFAIK casting from and to from a pointer to function to a void* is technically illegal - see the c++ faq -Code: Select all
typedef INT_PTR (FAR WINAPI *FARPROC)();
http://www.parashift.com/c++-faq-lite/p ... l#faq-33.8
Platform: MSW (Windows XP Pro)
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
Compiler: msvc 13.10.3077 (Free Toolkit)
wxWidgets: v2.6.0
I could provide my sample, which causes serious problems with virtual methods table. Lets assume, that you have code in dll:
So, this is windows specific case or casting to void* is really not good way to map methods from dll or other dynamic libraries???
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.
- Ryan Norton
- wxWorld Domination!
- Posts: 1319
- Joined: Mon Aug 30, 2004 6:01 pm
Out of curiousity, is your library created likerobal 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.
Code: Select all
wxDynamicLibrary library(wxT("my.dll"));