Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass nil to a var parameter?

There are quite a few API routines that take a pointer to some variable as a parameter that were translated to var parameters, yet can be specified as nil pointers according to the Windows help files.

As an example, the ChangeDisplaySettings function is declared as:

function ChangeDisplaySettings(var lpDevMode: TDeviceMode; dwFlags: DWORD): Longint; stdcall;

But the Windows help file clearly states that "Passing NULL for the lpDevMode parameter is the easiest way to return to the default mode after a dynamic mode change." The correct translation should have been:

function ChangeDisplaySettings(lpDevMode: PDeviceMode; dwFlags: DWORD): Longint; stdcall;

I'm posting this question and answer to help newbies get around these issues without having to re-declare the functions. I still remember that it was an issue for me in the beginning.

like image 794
Jannie Gerber Avatar asked Nov 22 '15 21:11

Jannie Gerber


1 Answers

One solution is to re-declare any such functions using pointers in place of the var parameters, but there is an easier solution. Simply cast a dereferenced nil-pointer to the correct type, e.g., for the ChangeDisplaySettings example, use the following to reset the display mode to the default registry settings:

ChangeDisplaySettings(TDeviceMode(nil^), 0);

or

ChangeDisplaySettings(PDeviceMode(nil)^, 0);

This way you are passing a var parameter that just happens to be located at memory address zero - the compiler is happy and you get to pass a nil pointer to the API routine!

Edit: From David Hefferman's comment, it seems that the standard practice is to rather re-declare such routines. Personally, I prefer to use the standard declarations if I can in my own personal units, but for professional work purposes I suggest that developers follow the standard practices.

like image 86
Jannie Gerber Avatar answered Dec 25 '22 01:12

Jannie Gerber