In this non-perfect example we interface with Windows Operating System to provide a functionality to print characters to standard output stream.
If you see some major issues, memory leaks or have better ideas, do not hesitate: improve this code and repost here.
Core highlight:
- This example uses
WriteFile()
Win32 API function withGetStdHandle(STD_OUTPUT_HANDLE)
.
How to use:
- This is a complete program, you can copy and paste into
.d
source file - Run using
rdmd yoursourcefile.d
version (Windows) @system @nogc:
// Example: Barebones print() function using Win32 Windows API
// Prints to standard output
import core.stdc.stdio : printf;
import core.sys.windows.winbase : GetStdHandle, STD_OUTPUT_HANDLE;
// Dlang headers are lacking function argument names to take advantage of : notation.
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile#syntax
// https://github.com/dlang/dmd/blob/a423208c7a5607a5af5e6b307f85179b7a8e9c20/druntime/src/core/sys/windows/winbase.d#L2073
extern(Windows) {
import core.sys.windows.basetsd : HANDLE;
import core.sys.windows.windef : BOOL, PCVOID, DWORD, PDWORD;
import core.sys.windows.winbase : LPOVERLAPPED;
BOOL WriteFile(HANDLE hFile, PCVOID lpBuffer, DWORD nNumberOfBytesToWrite, PDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
}
// print() becomes recursive if used inside print() itself
// prevent recursion inside print by passing insideItself argument
void print(string message = "\n", bool debugmode = false, bool insideItself = false) @trusted @nogc{
uint bytesWritten;
WriteFile(
hFile: GetStdHandle(STD_OUTPUT_HANDLE),
lpBuffer: message.ptr,
nNumberOfBytesToWrite: message.length,
lpNumberOfBytesWritten: &bytesWritten,
lpOverlapped: null
);
if (insideItself) return;
if (debugmode) {
print("\nNumberOfBytesToWrite: ", insideItself: true);
print(convertUintToString(message.length), insideItself: true);
print("\nNumberOfBytesWritten: ", insideItself: true);
print(convertUintToString(bytesWritten), insideItself: true);
}
}
string convertUintToString(uint n) @nogc {
import std.conv;
import std.experimental.allocator;
import std.experimental.allocator.mallocator;
alias a = Mallocator.instance;
auto s = a.makeArray(n.toChars);
return cast(string)s;
}
void main(){
print("HelloWorld", debugmode: true);
print("\nExample: ");
print("\nPrinting integer: ");
print(convertUintToString(5));
}
Expected output:
HelloWorld
NumberOfBytesToWrite: 10
NumberOfBytesWritten: 10
Example:
Printing integer: 5