PInvoke problem with int by reference

  • Thread starter Thread starter nicolasr
  • Start date Start date
N

nicolasr

Hi,

I have the following PInvoke problem:

I want to call the Win32 API SystemParametersInfo()
which has the following signature:

BOOL SystemParametersInfo(
UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni
);

the pinvoke.net site suggests the following declaration:

[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr
pvParam, uint fWinIni);

I'm interested in the case when uiAction is set to SPI_GETSCREENSAVEACTIVE
where pvParam "must point to a BOOL variable that receives..." (BOOL=32bit
signed int)

How to pass an 32-bit integer by reference to the above signature?

Any ideas appreciated.
Nicolas
 
nicolasr said:
Hi,

I have the following PInvoke problem:

I want to call the Win32 API SystemParametersInfo()
which has the following signature:

BOOL SystemParametersInfo(
UINT uiAction,
UINT uiParam,
PVOID pvParam,
UINT fWinIni
);

the pinvoke.net site suggests the following declaration:

[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam,
IntPtr pvParam, uint fWinIni);

I'm interested in the case when uiAction is set to SPI_GETSCREENSAVEACTIVE
where pvParam "must point to a BOOL variable that receives..." (BOOL=32bit
signed int)

How to pass an 32-bit integer by reference to the above signature?

The signature doesn't call for uiAction by reference. It wants it by value.
And if you need to pass a signed 32-bit integer, just declare it as
accepting a signed 32-bit integer.

[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(int uiAction, uint uiParam, IntPtr
pvParam, uint fWinIni);

Since C is not type safe, C dll's often play fast and loose with function
declarations. That declaration really only instructs you how to put 32-bits
on the stack. It says very little about which 32 bits. That's up to you.

David
 
thanks for your quick reply, but the parameter I have problems with is
<pvParam>, which is IntPtr.
Any idea?

Nick
 
nicolasr said:
thanks for your quick reply, but the parameter I have problems with is
<pvParam>, which is IntPtr.
Any idea?

Again, declare it as you would like to use it. Just remember that you can't
change the number of bytes you put on the stack. So pvParam MUST be 4
bytes, but it needn't be an IntPtr.

I'm interested in the case when uiAction is set to SPI_GETSCREENSAVEACTIVE
where pvParam "must point to a BOOL variable that receives..." (BOOL=32bit
signed int)

pointer to BOOL, is a pointer to an signed 32-bit integer, which you can get
by passing a ref int, instead of a IntPtr.

When you do this you should also alias the function, because you may need to
call it with different parameters

EG

//#define SPI_GETSCREENSAVEACTIVE 0x0010
const uint SPI_GETSCREENSAVEACTIVE = 0x0010;
const int TRUE = 1;
const int FALSE = 0;

[DllImport("user32.dll", SetLastError = true, EntryPoint =
"SystemParametersInfo")]
static extern int SystemParametersInfo_SPI_GETSCREENSAVEACTIVE(uint
uiAction, uint uiParam,
ref int pvParam, uint fWinIni);

static bool IsScreenSaveActive()
{
int bActive = -1;
int rc =
SystemParametersInfo_SPI_GETSCREENSAVEACTIVE(SPI_GETSCREENSAVEACTIVE, 0, ref
bActive, 0);
if (rc == 0)
{
throw new ApplicationException("SystemParametersInfo failed");
}
return (bActive == TRUE);
}

David
 
Back
Top