Difference between revisions of "D for Win32"

From D Wiki
Jump to: navigation, search
m (Windows Executables)
(console)
 
(13 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 12: Line 12:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Calling Conventions==
+
= 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 ... */
+
    /* ... function declarations ... */
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 32: 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 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
  
These are required:
+
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.
 
1. Instead of a '''main''' function serving as the entry point, a '''WinMain''' function is needed.
Line 41: Line 52:
 
2. '''WinMain''' must follow this form:
 
2. '''WinMain''' must follow this form:
  
<syntaxhighlight lang="C">
+
<syntaxhighlight lang="D">
 
import core.runtime;
 
import core.runtime;
 
import core.sys.windows.windows;
 
import core.sys.windows.windows;
Line 51: Line 62:
 
{
 
{
 
     int result;
 
     int result;
 
    void exceptionHandler(Throwable e) {
 
        throw e;
 
    }
 
  
 
     try
 
     try
 
     {
 
     {
         Runtime.initialize(&exceptionHandler);
+
         Runtime.initialize();
 
         result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
 
         result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
         Runtime.terminate(&exceptionHandler);
+
         Runtime.terminate();
 
     }
 
     }
     catch (Throwable e) // catch any uncaught exceptions
+
     catch (Throwable e)  
 
     {
 
     {
         MessageBoxA(null, e.toString().toStringz(), "Error",
+
         MessageBoxA(null, e.toString().toStringz(), null,
                     MB_OK | MB_ICONEXCLAMATION);
+
                     MB_ICONEXCLAMATION);
 
         result = 0;    // failed
 
         result = 0;    // failed
 
     }
 
     }
Line 91: Line 98:
 
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.
 
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==
+
= Windows Programming Examples =
 
A collection of over 140 Windows D programming code examples is available at [https://github.com/AndrejMitrovic/DWinProgramming this Github repository].
 
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.