Skip to main content

Types in Win32

Integer types

Compared to Dart, which has a single integer type that is used for storing any value between -263-1 and 263, the Win32 API has different-sized integer types in both unsigned and signed variants. The following table demonstrates the various integer types you'll commonly encounter when accessing Win32 APIs:

Common Win32 namesdart:ffi typeSizeSignedRange
BYTE, UINT8, CHARUint88 bitsNo0 to 255
INT8Int88 bitsYes-127 to 128
WORD, ATOM, UINT16, USHORTUint1616 bitsNo0 to 65535
INT16, SHORTInt1616 bitsYes-32767 to 32768
DWORD, UINT, UINT32, ULONGUint3232 bitsNo0 to 232
INT, INT32, LONGInt3232 bitsYes-231-1 to 231
DWORDLONG, ULONGLONG, UINT64, ULONG64Uint6464 bitsNo0 to 264
LONGLONG, INT64Int6464 bitsYes-263-1 to 263
HANDLE, LONG_PTR, UINT_PTR, ULONG_PTRIntPtr32/64 bitsNomatches pointer length

When you're calling a function and passing a value in, you don't have to worry about this: package:win32 includes all the metadata to convert from a Dart int type to the appropriate native representation.

However, knowing the type of data becomes important when a function is returning a value, since Win32 typically uses a Pointer argument that it fills with the relevant data.

package:win32 includes typedefs for all the common Win32 integer types, so you don't have to remember the size and sign of a type like DWORD.

For example, here's how to get the size of the system memory using Dart:

final lpMemorySize = calloc<ULONGLONG>();
GetPhysicallyInstalledSystemMemory(lpMemorySize);
final memorySizeMB = lpMemorySize.value ~/ 1024;
print('System has ${memorySizeMB}MB of RAM installed.');
free(lpMemorySize);

lpMemorySize could also be allocated as calloc<ULONG64>() or calloc<Uint64>(): they all mean the same thing.