DLL build with MSVC works but GCC wont

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7459
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: DLL build with MSVC works but GCC wont

Post by ONEEYEMAN »

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.
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: DLL build with MSVC works but GCC wont

Post by doublemax »

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
Use the source, Luke!
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: DLL build with MSVC works but GCC wont

Post by doublemax »

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/
Use the source, Luke!
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: DLL build with MSVC works but GCC wont

Post by doublemax »

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.
Use the source, Luke!
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: DLL build with MSVC works but GCC wont

Post by doublemax »

While the wxEntry will work for windows there is no functional equivalent for osx/linux
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.
i dont really want to insist the plugins are built with wxWidgets
Ok, that puts another 180° twist into the story :)
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 :oops:
Use the source, Luke!
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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?
keithsw11111
Earned a small fee
Earned a small fee
Posts: 11
Joined: Fri May 17, 2019 11:43 am

Re: DLL build with MSVC works but GCC wont

Post by keithsw11111 »

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.
Post Reply