Difference between revisions of "D for Win32"
(added windws executables) |
Adamdruppe (talk | contribs) (console) |
||
(16 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
− | + | = Introduction = | |
− | == | ||
− | |||
This describes the D implementation for 32 bit Windows systems. Naturally, Windows specific D features are not portable to other platforms. | This describes the D implementation for 32 bit Windows systems. Naturally, Windows specific D features are not portable to other platforms. | ||
Line 14: | Line 12: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | = Calling Conventions = | |
− | In C, the Windows API calling conventions are '''__stdcall'''. In D, it is simply: | + | In C, the Windows API calling conventions are [https://stackoverflow.com/questions/297654/what-is-stdcall/297661#297661 '''__stdcall''']. In D, it is simply: |
<syntaxhighlight lang="C"> | <syntaxhighlight lang="C"> | ||
extern (Windows) | extern (Windows) | ||
{ | { | ||
− | + | /* ... function declarations ... */ | |
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 34: | Line 32: | ||
If no function body is given, it's imported. If a function body is given, it's exported. | If no function body is given, it's imported. If a function body is given, it's exported. | ||
− | + | = Windows Executables = | |
Windows GUI applications can be written with D. A sample such can be found in \samples\d\winsamp.d | Windows GUI applications can be written with D. A sample such can be found in \samples\d\winsamp.d | ||
− | + | On Win32, you can pass -L/subsystem:windows if you don't want a console to be automatically allocated. | |
+ | |||
+ | Please note when compiling on Win64, you need to explicitly list -Lgdi32.lib -Luser32.lib on the build command. If you want the Windows subsystem too, use -L/subsystem:windows -L/entry:mainCRTStartup. | ||
+ | |||
+ | If using ldc instead of dmd, use -L/entry:wmainCRTStartup instead of mainCRTStartup; note the "w". | ||
+ | |||
+ | It is possible to do this with a mixin too in a library, see arsd.simpledisplay mixin EnableWindowsSubsystem for an example. | ||
+ | |||
+ | With the Windows subsystem, there is no console, so standard writeln will throw! | ||
+ | |||
+ | |||
+ | Alternative option: | ||
+ | |||
+ | 1. Instead of a '''main''' function serving as the entry point, a '''WinMain''' function is needed. | ||
− | + | 2. '''WinMain''' must follow this form: | |
− | '''WinMain''' must follow this form: | ||
− | <syntaxhighlight lang=" | + | <syntaxhighlight lang="D"> |
import core.runtime; | import core.runtime; | ||
import core.sys.windows.windows; | import core.sys.windows.windows; | ||
Line 52: | Line 62: | ||
{ | { | ||
int result; | int result; | ||
− | |||
− | |||
− | |||
− | |||
try | try | ||
{ | { | ||
− | Runtime.initialize( | + | Runtime.initialize(); |
result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); | result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); | ||
− | Runtime.terminate( | + | Runtime.terminate(); |
} | } | ||
− | catch (Throwable e) | + | catch (Throwable e) |
{ | { | ||
− | MessageBoxA(null, e.toString().toStringz(), | + | MessageBoxA(null, e.toString().toStringz(), null, |
− | + | MB_ICONEXCLAMATION); | |
result = 0; // failed | result = 0; // failed | ||
} | } | ||
− | + | return result; | |
} | } | ||
Line 81: | Line 87: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | The myWinMain() function is where the user code goes, the rest of WinMain is boilerplate to initialize and shut down the D runtime system. | + | The '''myWinMain()''' function is where the user code goes, the rest of '''WinMain''' is boilerplate to initialize and shut down the D runtime system. |
− | A .def (Module Definition File) with at least the following two lines in it: | + | |
+ | 3. A '''.def''' ([http://www.digitalmars.com/ctg/ctgDefFiles.html Module Definition File]) with at least the following two lines in it: | ||
+ | <pre> | ||
EXETYPE NT | EXETYPE NT | ||
SUBSYSTEM WINDOWS | SUBSYSTEM WINDOWS | ||
+ | </pre> | ||
Without those, Win32 will open a text console window whenever the application is run. | Without those, Win32 will open a text console window whenever the application is run. | ||
− | The presence of WinMain() is recognized by the compiler causing it to emit a reference to __acrtused_dll and the phobos.lib runtime library. | + | |
+ | 4. The presence of '''WinMain()''' is recognized by the compiler causing it to emit a reference to [http://www.digitalmars.com/ctg/acrtused.html __acrtused_dll] and the phobos.lib runtime library. | ||
+ | |||
+ | = Windows Programming Examples = | ||
+ | A collection of over 140 Windows D programming code examples is available at [https://github.com/AndrejMitrovic/DWinProgramming this Github repository]. | ||
+ | |||
+ | |||
+ | [[Category:HowTo]] | ||
+ | [[Category:Windows]] |
Latest revision as of 13:33, 28 May 2024
Introduction
This describes the D implementation for 32 bit Windows systems. Naturally, Windows specific D features are not portable to other platforms.
Instead of the:
#include <windows.h>
of C, in D there is:
import core.sys.windows.windows;
Calling Conventions
In C, the Windows API calling conventions are __stdcall. In D, it is simply:
extern (Windows)
{
/* ... function declarations ... */
}
The Windows linkage attribute sets both the calling convention and the name mangling scheme to be compatible with Windows.
For functions that in C would be __declspec(dllimport) or __declspec(dllexport), use the export attribute:
export void func(int foo);
If no function body is given, it's imported. If a function body is given, it's exported.
Windows Executables
Windows GUI applications can be written with D. A sample such can be found in \samples\d\winsamp.d
On Win32, you can pass -L/subsystem:windows if you don't want a console to be automatically allocated.
Please note when compiling on Win64, you need to explicitly list -Lgdi32.lib -Luser32.lib on the build command. If you want the Windows subsystem too, use -L/subsystem:windows -L/entry:mainCRTStartup.
If using ldc instead of dmd, use -L/entry:wmainCRTStartup instead of mainCRTStartup; note the "w".
It is possible to do this with a mixin too in a library, see arsd.simpledisplay mixin EnableWindowsSubsystem for an example.
With the Windows subsystem, there is no console, so standard writeln will throw!
Alternative option:
1. Instead of a main function serving as the entry point, a WinMain function is needed.
2. WinMain must follow this form:
import core.runtime;
import core.sys.windows.windows;
import std.string;
extern (Windows)
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
int result;
try
{
Runtime.initialize();
result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
Runtime.terminate();
}
catch (Throwable e)
{
MessageBoxA(null, e.toString().toStringz(), null,
MB_ICONEXCLAMATION);
result = 0; // failed
}
return result;
}
int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// ... insert user code here ...
return 0;
}
The myWinMain() function is where the user code goes, the rest of WinMain is boilerplate to initialize and shut down the D runtime system.
3. A .def (Module Definition File) with at least the following two lines in it:
EXETYPE NT SUBSYSTEM WINDOWS
Without those, Win32 will open a text console window whenever the application is run.
4. The presence of WinMain() is recognized by the compiler causing it to emit a reference to __acrtused_dll and the phobos.lib runtime library.
Windows Programming Examples
A collection of over 140 Windows D programming code examples is available at this Github repository.