Example: Barebones print() statement, interfacing with Windows Operating System.

BoQsc vaidas.boqsc at gmail.com
Tue Nov 28 10:49:50 UTC 2023


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()`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile) Win32 API function with `GetStdHandle(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
```


More information about the Digitalmars-d-learn mailing list