DLL build with MSVC works but GCC wont
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
DLL build with MSVC works but GCC wont
I have built a wxWidgets GUI app and then created a wxWidgets DLL which contains a IMPLEMENT_APP_NO_MAIN app with UI.
When I compile it using MSVC it works perfectly. When the DLL loads the wxTheApp macro in the DLL returns null which is then correctly initialised using a call to wxEntryStart follow by GUI creation in a call to CallOnInit.
When I compile exactly the same code in gcc it doesnt work. The DLL compiles and loads dynamically but when i check wxTheApp before calling wxEntryStart instead of being null it has the value that the calling application has ... so of course when i call CallOnInit it tries to double initialise the calling application.
So I figure this is a compiling or linking issue.
my gcc compile options are:
g++.exe -fno-strict-aliasing -Wno-unused-local-typedefs -DwxUSE_UNICODE -O2 -pedantic -std=c++1z -fPIC -m64 -pipe -mthreads -static-libgcc -fno-keep-inline-dllexport -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DNDEBUG -D_USE_MATH_DEFINES
my gcc link options are:
g++.exe -shared -Wl,--dll -O2 -s -m64 -Wl,-Map=xxx.map
Interested in any hints as to what I might be doing wrong.
When I compile it using MSVC it works perfectly. When the DLL loads the wxTheApp macro in the DLL returns null which is then correctly initialised using a call to wxEntryStart follow by GUI creation in a call to CallOnInit.
When I compile exactly the same code in gcc it doesnt work. The DLL compiles and loads dynamically but when i check wxTheApp before calling wxEntryStart instead of being null it has the value that the calling application has ... so of course when i call CallOnInit it tries to double initialise the calling application.
So I figure this is a compiling or linking issue.
my gcc compile options are:
g++.exe -fno-strict-aliasing -Wno-unused-local-typedefs -DwxUSE_UNICODE -O2 -pedantic -std=c++1z -fPIC -m64 -pipe -mthreads -static-libgcc -fno-keep-inline-dllexport -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DNDEBUG -D_USE_MATH_DEFINES
my gcc link options are:
g++.exe -shared -Wl,--dll -O2 -s -m64 -Wl,-Map=xxx.map
Interested in any hints as to what I might be doing wrong.
Re: DLL build with MSVC works but GCC wont
Hi,
Couple of questions:
1. Version of wxWidgets
2. Version of OS?
3. Version of compilers?
4. Did you use Cygwin environment or just plain MinGW? Or maybe you were cross-compiling? Did you mix them up?
5. Did you use EXACTLY the same compiler command line to build the library and the application?
And finally - does dll sample works for you for both compilers?
Thank you.
Couple of questions:
1. Version of wxWidgets
2. Version of OS?
3. Version of compilers?
4. Did you use Cygwin environment or just plain MinGW? Or maybe you were cross-compiling? Did you mix them up?
5. Did you use EXACTLY the same compiler command line to build the library and the application?
And finally - does dll sample works for you for both compilers?
Thank you.
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
1. Version of wxWidgets - 3.1.1
2. Version of OS? - Windows 10 ... up to date
3. Version of compilers? - MSVC 2019, GCC 7.2.0 (mingw)
4. Did you use Cygwin environment or just plain MinGW? Or maybe you were cross-compiling? Did you mix them up? - Mingw
5. Did you use EXACTLY the same compiler command line to build the library and the application?
And finally - does dll sample works for you for both compilers?
The answer to this has to be no as one is a dll and the other an executable so at least the link step must be different.
Compile options compiling the executable are identical
g++.exe -fno-strict-aliasing -Wno-unused-local-typedefs -DwxUSE_UNICODE -O2 -pedantic -std=c++1z -m64 -pipe -mthreads -static-libgcc -fno-keep-inline-dllexport -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DNDEBUG -D_USE_MATH_DEFINES
The linker options are not
g++.exe -s -m64 -O2 -Wl,-Map=xxx.map
It has the --dll and -shared options removed
2. Version of OS? - Windows 10 ... up to date
3. Version of compilers? - MSVC 2019, GCC 7.2.0 (mingw)
4. Did you use Cygwin environment or just plain MinGW? Or maybe you were cross-compiling? Did you mix them up? - Mingw
5. Did you use EXACTLY the same compiler command line to build the library and the application?
And finally - does dll sample works for you for both compilers?
The answer to this has to be no as one is a dll and the other an executable so at least the link step must be different.
Compile options compiling the executable are identical
g++.exe -fno-strict-aliasing -Wno-unused-local-typedefs -DwxUSE_UNICODE -O2 -pedantic -std=c++1z -m64 -pipe -mthreads -static-libgcc -fno-keep-inline-dllexport -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DNDEBUG -D_USE_MATH_DEFINES
The linker options are not
g++.exe -s -m64 -O2 -Wl,-Map=xxx.map
It has the --dll and -shared options removed
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
Sorry ... I didnt answer the DLL sample question ... mainly because I dont see how it is relevant. In both cases the DLL compiles and is called so there is no reason why the dll sample would not work. The issue arises with the use of the wxApp bootstrapping in the DLL and specifically the wxTheApp macro (which is just a wrapper around a HInstance not working the same under gcc and mingw.
I will build a minimal example to demonstrate the problem.
I will build a minimal example to demonstrate the problem.
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
I have built a minimal sample project and placed it in github.
https://bitbucket.org/keithsw1111/exe_dll/src/master/
When run just press load, press unload and then close the exe frame.
Check log.txt to see what happened internally.
This is the log.txt file when run with visual studio:
exe.exe OnInit()
exe.exe exeframe constructor
exe.exe exeframe User pressed load button.
exe.exe DoLoad.
dll.dll dll process attach
exe.exe dll.dll loaded.
exe.exe dll.dll dll_Load found.
dll.dll dll_Load reached
dll.dll dll OnInit
dll.dll dllFrame constructor
dll.dll dll_Load success
exe.exe exeframe User pressed unload button.
exe.exe DoUnload.
exe.exe dll.dll dll_Unload found.
dll.dll dll_Unload reached
dll.dll dll OnExit()
dll.dll dll_Unload success
dll.dll dll process detach
exe.exe OnExit
This is the file when run using the gcc built exe/dll
exe.exe OnInit()
exe.exe exeframe constructor
exe.exe exeframe User pressed load button.
exe.exe DoLoad.
dll.dll dll process attach
exe.exe dll.dll loaded.
exe.exe dll.dll dll_Load found.
dll.dll dll_Load reached
exe.exe OnInit()
exe.exe exeframe constructor
dll.dll dll_Load success
Note how the OnInit is called on the exe twice rather than calling the OnInit in the dll. Otherwise the dll is loading and being called ok.
https://bitbucket.org/keithsw1111/exe_dll/src/master/
When run just press load, press unload and then close the exe frame.
Check log.txt to see what happened internally.
This is the log.txt file when run with visual studio:
exe.exe OnInit()
exe.exe exeframe constructor
exe.exe exeframe User pressed load button.
exe.exe DoLoad.
dll.dll dll process attach
exe.exe dll.dll loaded.
exe.exe dll.dll dll_Load found.
dll.dll dll_Load reached
dll.dll dll OnInit
dll.dll dllFrame constructor
dll.dll dll_Load success
exe.exe exeframe User pressed unload button.
exe.exe DoUnload.
exe.exe dll.dll dll_Unload found.
dll.dll dll_Unload reached
dll.dll dll OnExit()
dll.dll dll_Unload success
dll.dll dll process detach
exe.exe OnExit
This is the file when run using the gcc built exe/dll
exe.exe OnInit()
exe.exe exeframe constructor
exe.exe exeframe User pressed load button.
exe.exe DoLoad.
dll.dll dll process attach
exe.exe dll.dll loaded.
exe.exe dll.dll dll_Load found.
dll.dll dll_Load reached
exe.exe OnInit()
exe.exe exeframe constructor
dll.dll dll_Load success
Note how the OnInit is called on the exe twice rather than calling the OnInit in the dll. Otherwise the dll is loading and being called ok.
Re: DLL build with MSVC works but GCC wont
Is the DLL totally independent of the exe, so that it also be used with non-wxWidgets exes?
Then you need to use a method that's shown in the "dll" sample that puts the wxWidgets instance from the DLL in a separate thread.
If it's just a normal "dynamic library", there is not supposed to be a wxApp in the DLL. Just like a statically linked library, it's just a bunch of functions. You don't want multiple wxApp instances unless you use the method i mentioned above.
Depending on what you actually want to do, this could be interesting, too:
https://github.com/T-Rex/wxModularApp
Then you need to use a method that's shown in the "dll" sample that puts the wxWidgets instance from the DLL in a separate thread.
If it's just a normal "dynamic library", there is not supposed to be a wxApp in the DLL. Just like a statically linked library, it's just a bunch of functions. You don't want multiple wxApp instances unless you use the method i mentioned above.
Depending on what you actually want to do, this could be interesting, too:
https://github.com/T-Rex/wxModularApp
Use the source, Luke!
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
Ok Max ... I am deep in a rabbit hole here and beginning to suspect I am making it much harder than I need to. I endeavoured to follow your instructions and ran into more issues ... but replacing the GetModuleHandle(NULL) with a GetModuleHandle("dll.dll") got the UI up but then I have asserts re wxMutexGuiLeaveOrEnter not on the main thread and it is downhill from there.
So time to step back and start with my purpose here. We have a large open source multiplatform wxWidgets application (xlights.org). I am trying to add the ability to build plugins in dlls. These plugins will want to display non modal dialogs (which I have been trying to achieve with a main frame).
Is there a better way to achieve this?
So time to step back and start with my purpose here. We have a large open source multiplatform wxWidgets application (xlights.org). I am trying to add the ability to build plugins in dlls. These plugins will want to display non modal dialogs (which I have been trying to achieve with a main frame).
Is there a better way to achieve this?
Re: DLL build with MSVC works but GCC wont
You should take a closer look into the wxModularApp link i posted.
Here's an article that describes the method in more detail, use Google Translate if needed:
https://wxwidgets.info/razrabotka-kross ... wxwidgets/
Here's an article that describes the method in more detail, use Google Translate if needed:
https://wxwidgets.info/razrabotka-kross ... wxwidgets/
Use the source, Luke!
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
I have updated the bitbucket code to create another thread and then display a modeless dialog rather than a frame. It kind of works but you can tell it isnt right and when I tried to apply it to the main code base it crashes because wxWidgets just does not seem to be in the right state.
In visual studio (under debug i get asserts but it seems to work)
In gcc it runs ok but when i exit it exits with a non zero exit code.
But the fact it kind of works I think is more like good luck than correctness.
Again ... I would appreciate feedback ... did i follow the instructions correctly.
In visual studio (under debug i get asserts but it seems to work)
In gcc it runs ok but when i exit it exits with a non zero exit code.
But the fact it kind of works I think is more like good luck than correctness.
Again ... I would appreciate feedback ... did i follow the instructions correctly.
Re: DLL build with MSVC works but GCC wont
If you use the method with a separate thread, wxWidgets itself must be initialized from that thread, so you can't use wxThread. That's the reason why the "dll" sample uses a native Windows thread.
However, only for Windows a working sample of that method exists, and it seems you need a Linux and OSX version, too. This method also makes the communication between plugin and main application more complicated and i assume you want to make the writing of plugins through others users as simple as possible.
Therefore i'd suggest to check TRex's code and forget about the version with a separate thread.
Unfortunately i've never done anything like this myself, so i can't provide a simple, working sample.
However, only for Windows a working sample of that method exists, and it seems you need a Linux and OSX version, too. This method also makes the communication between plugin and main application more complicated and i assume you want to make the writing of plugins through others users as simple as possible.
Therefore i'd suggest to check TRex's code and forget about the version with a separate thread.
Unfortunately i've never done anything like this myself, so i can't provide a simple, working sample.
Use the source, Luke!
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
Ok ... just playing this back to ensure i have it right.
1. The launching of the thread needs to be native. This is not a big overhead. In the thread I need to call wxInitialise etc to set everything up.
2. The interaction between the plugin and the main code also needs to recognise it is not on the main thread and thus not interact directly with the exes ui ... i am good with that.
3. While the wxEntry will work for windows there is no functional equivalent for osx/linux ... so at this point i am going to be stuck. Is this because that is impossible ... or more something that no one has built but i might be able to come up with a linux/osx equivalent.
1. The launching of the thread needs to be native. This is not a big overhead. In the thread I need to call wxInitialise etc to set everything up.
2. The interaction between the plugin and the main code also needs to recognise it is not on the main thread and thus not interact directly with the exes ui ... i am good with that.
3. While the wxEntry will work for windows there is no functional equivalent for osx/linux ... so at this point i am going to be stuck. Is this because that is impossible ... or more something that no one has built but i might be able to come up with a linux/osx equivalent.
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
I have tried every combination I can think of in the bitbucket code and it still isnt right.
I did look at the wxModularApp code but that is going to take some time as it only seems to have cmake builds and I have never managed to get a cmake to work ... there is always something not quite right and thus it doesnt work. From the code itself it seems to place constraints on the dll that wont be workable as i dont really want to insist the plugins are built with wxWidgets but there may still be a gem in there that helps me work this out.
Thanks for your input so far. If you can see anything else in the bitbucket code I am all ears ... otherwise I guess I need to spend more time on the modular app code.
I did look at the wxModularApp code but that is going to take some time as it only seems to have cmake builds and I have never managed to get a cmake to work ... there is always something not quite right and thus it doesnt work. From the code itself it seems to place constraints on the dll that wont be workable as i dont really want to insist the plugins are built with wxWidgets but there may still be a gem in there that helps me work this out.
Thanks for your input so far. If you can see anything else in the bitbucket code I am all ears ... otherwise I guess I need to spend more time on the modular app code.
Re: DLL build with MSVC works but GCC wont
No, the wxEntry part and everything else does exists and is identical for all platforms. I just meant that the "dll" sample uses Windows specific code and there is no Linux or OSX version. So you'll have to experiment a bit on that side.While the wxEntry will work for windows there is no functional equivalent for osx/linux
Ok, that puts another 180° twist into the storyi dont really want to insist the plugins are built with wxWidgets
In that case the thread-based solution is preferable again. But that also means that you should be able to copy the "DLL" sample and start from there.
Sorry for the confusion
Use the source, Luke!
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
The thing that continues to puzzle me is why i can get it working in visual studio but not gcc.
Could it be i am statically linking visual studio and dynamically linking gcc?
Would that explain why vs has a zero instance handle when started while gcc has the instance already set by the host app?
Could it be i am statically linking visual studio and dynamically linking gcc?
Would that explain why vs has a zero instance handle when started while gcc has the instance already set by the host app?
-
- Earned a small fee
- Posts: 11
- Joined: Fri May 17, 2019 11:43 am
Re: DLL build with MSVC works but GCC wont
Ok ... I think i have it working ... the secret was recognising that if wxTheApp in the dll is null then i need to create a thread and initialise wxwidgets ... but if it is not null then i should just create the dialog and not try to initialise wxwidgets at all.
I will leave the code up for future reference.
Now to merge it into my project and hope that works.
I will leave the code up for future reference.
Now to merge it into my project and hope that works.