D programming Language



Download 1.66 Mb.
Page41/47
Date08.01.2017
Size1.66 Mb.
#7507
1   ...   37   38   39   40   41   42   43   44   ...   47

zip





stdio


int printf(char* format, ...)

C printf() function.


D for Win32


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

of C, in D there is:

import 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 \dmd\samples\d\winsamp.d

These are required:



  1. Instead of a main function serving as the entry point, a WinMain function is needed.

  2. WinMain must follow this form:

  3. import windows;



  4. extern (C) void gc_init();

  5. extern (C) void gc_term();

  6. extern (C) void _minit();

  7. extern (C) void _moduleCtor();

  8. extern (C) void _moduleUnitTests();



  9. extern (Windows)

  10. int WinMain(HINSTANCE hInstance,

  11. HINSTANCE hPrevInstance,

  12. LPSTR lpCmdLine,

  13. int nCmdShow)

  14. {

  15. int result;



  16. gc_init(); // initialize garbage collector

  17. _minit(); // initialize module constructor table



  18. try

  19. {

  20. _moduleCtor(); // call module constructors

  21. _moduleUnitTests(); // run unit tests (optional)



  22. result = doit(); // insert user code here

  23. }



  24. catch (Object o) // catch any uncaught exceptions

  25. {

  26. MessageBoxA(null, (char *)o.toString(), "Error",

  27. MB_OK | MB_ICONEXCLAMATION);

  28. result = 0; // failed

  29. }



  30. gc_term(); // run finalizers; terminate garbage collector

  31. return result;

  32. }

The doit() function is where the user code goes, the rest of WinMain is boilerplate to initialize and shut down the D runtime system.



  1. A .def (Module Definition File) with at least the following two lines in it:

  2. EXETYPE NT

  3. SUBSYSTEM WINDOWS

Without those, Win32 will open a text console window whenever the application is run.



  1. The presence of WinMain() is recognized by the compiler causing it to emit a reference to __acrtused and the phobos.lib runtime library.

DLLs (Dynamic Link Libraries)


DLLs can be created in D in roughly the same way as in C. A DllMain() is required, looking like:

import windows;

HINSTANCE g_hInst;
extern (C)

{

void gc_init();



void gc_term();

void _minit();

void _moduleCtor();

void _moduleUnitTests();

}
extern (Windows)

BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)

{

switch (ulReason)



{

case DLL_PROCESS_ATTACH:

gc_init(); // initialize GC

_minit(); // initialize module list

_moduleCtor(); // run module constructors

_moduleUnitTests(); // run module unit tests

break;
case DLL_PROCESS_DETACH:

gc_term(); // shut down GC

break;
case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

// Multiple threads not supported yet

return false;

}

g_hInst=hInstance;



return true;

}

Notes:



  • The _moduleUnitTests() call is optional.

  • It's a little crude, I hope to improve it.

  • The presence of DllMain() is recognized by the compiler causing it to emit a reference to __acrtused_dll and the phobos.lib runtime library.

Link with a .def (Module Definition File) along the lines of:

LIBRARY MYDLL

DESCRIPTION 'My DLL written in D'
EXETYPE NT

CODE PRELOAD DISCARDABLE

DATA PRELOAD SINGLE
EXPORTS

DllGetClassObject @2

DllCanUnloadNow @3

DllRegisterServer @4

DllUnregisterServer @5

The functions in the EXPORTS list are for illustration. Replace them with the actual exported functions from MYDLL.


Memory Allocation


D DLLs use garbage collected memory management. The question is what happens when pointers to allocated data cross DLL boundaries? Other DLLs, or callers to a D DLL, may even be written in another language and may have no idea how to interface with D's garbage collector.

There are many approaches to solving this problem. The most practical approaches are to assume that other DLLs have no idea about D. To that end, one of these should work:



  • Do not return pointers to D gc allocated memory to the caller of the DLL. Instead, have the caller allocate a buffer, and have the DLL fill in that buffer.

  • Retain a pointer to the data within the D DLL so the GC will not free it. Establish a protocol where the caller informs the D DLL when it is safe to free the data.

  • Use operating system primitives like VirtualAlloc() to allocate memory to be transferred between DLLs.

  • Use COM interfaces, rather than D class objects. D supports the AddRef()/Release() protocol for COM interfaces. Most languages implemented on Win32 have support for COM, making it a good choice.


Download 1.66 Mb.

Share with your friends:
1   ...   37   38   39   40   41   42   43   44   ...   47




The database is protected by copyright ©ininet.org 2024
send message

    Main page