-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
When declaring a native Windows function like SetFilePointerEx
, where the second parameter (liDistanceToMove
) is an input value typically passed by value in native C/C++:
// Example native function declaration
// liDistanceToMove is the distance to move the file pointer, intended to be passed BY VALUE.
public native boolean SetFilePointerEx(
HANDLE hFile,
LARGE_INTEGER liDistanceToMove, // <--- THE PROBLEM IS HERE
ULONG_PTRByReference lpNewFilePointer,
int dwMoveMethod
);
I did not think much of it and simply used the base LARGE_INTEGER class for the input parameter. I immediately found that it was incorrectly passed as reference (or address) to the native side!
I am confused about why LARGE_INTEGER
, a very common 8-byte structure in Windows APIs, was designed without a corresponding ByValue class. On many calling conventions, small structures like this are passed by value.
Below are my points of view about this issue.
-
Given that this structure is frequently used as a pass-by-value input parameter (as in SetFilePointerEx), why not just adding a static nested
ByValue
class toLARGE_INTEGER
(e.g.,LARGE_INTEGER.ByValue
)? -
Since LARGE_INTEGER is semantically equivalent to a 64-bit number, and is designed to represent a single value, how about considering treating it as a
numerical type
instead of a standardStructure
?