digitalmars.D.learn - Example: Barebones print() statement, interfacing with Windows
- BoQsc (81/81) Nov 28 2023 In this non-perfect example we interface with Windows Operating
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/n -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 ```
Nov 28 2023