Thread overview | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 28, 2020 Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Hi, I'm fairly new to D, just playing around with Win32 bindings. I have a Win32 hello world that works when build via `dmd .\source\app test-win32.def`. I'm now trying to build the application via `dub`, but I cannot find what configuration I would need to do so. By default, just running `dub`, I get the following error: ``` Performing "debug" build using C:\D\dmd2\windows\bin\dmd.exe for x86_64. test-win32 ~master: building configuration "application"... Linking... test-win32.obj : error LNK2019: unresolved external symbol MessageBoxA referenced in function WinMain .dub\build\application-debug-windows-x86_64-dmd_2091-347A0A76992D6DB80483AD860293313E\test-win32.exe : fatal error LNK1120: 1 unresolved externals Error: linker exited with status 1120 C:\D\dmd2\windows\bin\dmd.exe failed with exit code 1. ``` The code is the one from https://wiki.dlang.org/D_for_Win32, with a simple extra `MessageBoxA` in the function `myWinMain`. I'm a bit surprised to see a linking error given that building directly from `dmd` seems to work fine without any flag. What am I missing? |
April 28, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | On Tuesday, 28 April 2020 at 19:25:06 UTC, Sam E. wrote:
> I'm a bit surprised to see a linking error given that building directly from `dmd` seems to work fine without any flag.
dmd directly uses -m32 whereas dub by default uses -m32mscoff to dmd.
The mscoff linker (also used for -m64 btw) doesn't add the user32 library by default, you must explicitly add it.
So with dub just add the user32 library to your config file and it should be ok. (I don't recall the syntax for that off the top of my head)
|
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Tuesday, 28 April 2020 at 20:18:29 UTC, Adam D. Ruppe wrote: > On Tuesday, 28 April 2020 at 19:25:06 UTC, Sam E. wrote: >> I'm a bit surprised to see a linking error given that building directly from `dmd` seems to work fine without any flag. > > dmd directly uses -m32 whereas dub by default uses -m32mscoff to dmd. > > The mscoff linker (also used for -m64 btw) doesn't add the user32 library by default, you must explicitly add it. > > So with dub just add the user32 library to your config file and it should be ok. (I don't recall the syntax for that off the top of my head) Thanks, that seems to link after adding `libs "user32"` to my `dub.sdl` file. Though the program built with dub is now crashing at runtime when calling `writeln` within the `WinMain` block. The exception error is: > Exception has occurred: W32/0xc0000096 > Unhandled exception at 0x00007FF643C5AFE4 in test-win32.exe: 0xC0000096: Privileged instruction. So it feels that something else is missing or wrong. Any pointer would be helpful :) Screenshot of the call site: https://postimg.cc/5YtY9PRQ Screenshot of the expection: https://postimg.cc/K3vKz0pg |
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | On Wednesday, 29 April 2020 at 09:43:53 UTC, Sam E. wrote: > Though the program built with dub is now crashing at runtime when calling `writeln` within the `WinMain` block. > > The exception error is: > >> Exception has occurred: W32/0xc0000096 >> Unhandled exception at 0x00007FF643C5AFE4 in test-win32.exe: 0xC0000096: Privileged instruction. > > So it feels that something else is missing or wrong. > > Any pointer would be helpful :) > > Screenshot of the call site: https://postimg.cc/5YtY9PRQ > Screenshot of the expection: https://postimg.cc/K3vKz0pg Most likely because you're calling writeln before initializing the runtime. Also, when using WinMain, you aren't going to see any output from writeln because you won't have a console window. The linker will create a "Windows subsystem" app rather than a "Console subsystem". Really, there's no reason at all to use WinMain. Just create a standard main function. Then you don't need to worry about manually initializing the runtime and you'll have a console window by default. You can always turn it off in anything you want to ship without the console by adding the appropriate dflags to your dub file: -L/SUBSYSTEM:WINDOWS -L/ENTRY:mainCRTStartup Conversely, you can get the console window in a WinMain app with: -L/SUBSYSTEM:CONSOLE -L/ENTRY:WinMainCRTStartup Though, again, there's really no reason to use WinMain. The /SUBSYSTEM flag works with the default OPTLINK linker and Microsoft's link.exe. You don't need the /ENTRY flag with optlink. It will do the right thing based on the /SUBSYSTEM flag. https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2019 https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2019 |
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | > Though the program built with dub is now crashing at runtime when calling `writeln` within the `WinMain` block.
Back then when I was trying to use writeln (or any standard output function like printf)in a non-console app in Windows it used to crash, I don't know exact reason behind it but you might want to use AllocConsole to workaround it.
If the same code works fine with -m32 but not -m32mscoff (or -m64) then I have no idea.
|
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Wednesday, 29 April 2020 at 10:12:29 UTC, Mike Parker wrote: > Most likely because you're calling writeln before initializing the runtime. Of course, that was it, thanks for the help Mike! > Also, when using WinMain, you aren't going to see any output from writeln because you won't have a console window. The linker will create a "Windows subsystem" app rather than a "Console subsystem". Thanks again, you're right, I didn't realize that would be the case. > Really, there's no reason at all to use WinMain. Just create a standard main function. Then you don't need to worry about manually initializing the runtime and you'll have a console window by default. You can always turn it off in anything you want to ship without the console by adding the appropriate dflags to your dub file: > > -L/SUBSYSTEM:WINDOWS -L/ENTRY:mainCRTStartup > > Conversely, you can get the console window in a WinMain app with: > > -L/SUBSYSTEM:CONSOLE -L/ENTRY:WinMainCRTStartup > > Though, again, there's really no reason to use WinMain. I took the WinMain from https://wiki.dlang.org/D_for_Win32, should that documentation be updated to use a normal main function instead? Also the details regarding linker flags may be a good addition to that wiki page. |
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ahmet Sait | On Wednesday, 29 April 2020 at 10:19:39 UTC, Ahmet Sait wrote:
>> Though the program built with dub is now crashing at runtime when calling `writeln` within the `WinMain` block.
>
> Back then when I was trying to use writeln (or any standard output function like printf)in a non-console app in Windows it used to crash, I don't know exact reason behind it but you might want to use AllocConsole to workaround it.
>
> If the same code works fine with -m32 but not -m32mscoff (or -m64) then I have no idea.
To be honest, I haven't yet found the way to switch between -m32 and -m64 (or other) via dub :)
|
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | On Wednesday, 29 April 2020 at 10:26:40 UTC, Sam E. wrote:
>> Really, there's no reason at all to use WinMain. Just create a standard main function. Then you don't need to worry about manually initializing the runtime and you'll have a console window by default. You can always turn it off in anything you want to ship without the console by adding the appropriate dflags to your dub file:
>>
>> -L/SUBSYSTEM:WINDOWS -L/ENTRY:mainCRTStartup
>>
>> Conversely, you can get the console window in a WinMain app with:
>>
>> -L/SUBSYSTEM:CONSOLE -L/ENTRY:WinMainCRTStartup
>>
>> Though, again, there's really no reason to use WinMain.
>
> I took the WinMain from https://wiki.dlang.org/D_for_Win32, should that documentation be updated to use a normal main function instead? Also the details regarding linker flags may be a good addition to that wiki page.
Just to confirm what Mike was saying: removing the WinMain completely and using a normal main function with calls to Win32 functions builds and works perfectly fine, that's a way nicer approach.
|
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | On 29/04/2020 10:27 PM, Sam E. wrote:
> To be honest, I haven't yet found the way to switch between -m32 and -m64 (or other) via dub :)
$ dub build --arch=x86
$ dub build --arch=x86_64
|
April 29, 2020 Re: Building Win32 application via dub | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sam E. | On Wednesday, 29 April 2020 at 10:27:35 UTC, Sam E. wrote:
>
> To be honest, I haven't yet found the way to switch between -m32 and -m64 (or other) via dub :)
Pass the -a flag on the dub command line with the appropriate argument:
For -m32: -ax86
For -m32mscoff: -ax86_mscoff
For -m64: -ax86_64
Note that on 64-bit Windows, recent versions of dub will be calling the compiler with -m64 by default.
|
Copyright © 1999-2021 by the D Language Foundation