For a function marshalled like that:
/*************************************************
* DWORD WINAPI WlanHostedNetworkSetProperty(
* _In_ HANDLE hClientHandle,
* _In_ _WLAN_HOSTED_NETWORK_OPCODE OpCode,
* _In_ DWORD dwDataSize,
* _In_ PVOID pvData,
* _Out_opt_ P_WLAN_HOSTED_NETWORK_REASON pFailReason,
* _Reserved_ PVOID pvReserved
* );
*************************************************/
[DllImport("Wlanapi.dll", SetLastError = true)]
public static extern UInt32 WlanHostedNetworkSetProperty(
[In] IntPtr hClientHandle,
[In] _WLAN_HOSTED_NETWORK_OPCODE OpCode,
[In] UInt32 dwDataSize,
[In] IntPtr pvData,
[Out] out _WLAN_HOSTED_NETWORK_REASON pFailReason,
[In, Out] IntPtr pvReserved
);
Microsoft documentation says that when I pass
_WLAN_HOSTED_NETWORK_OPCODE._WLAN_HOSTED_NETWORK_OPCODE_enable
as a parameter of OpCode, the value of pvData should be a pointer to a Boolean value.
Hereis the documentation for that function
I have no idea though how to get an IntPtr to point to a Boolean?
Should it be done in a similar way to when I pass a pointer to a struct as pvData :
int size = Marshal.SizeOf(settings); //*settings* is a struct with some data
IntPtr pSettings = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(settings, pSettings, true);
/* use the IntPtr */
Marshal.FreeHGlobal(pSettings);
But instead I marshal the Boolean? Or is there an easier way?
Thanks for your help all lovely people.
Win32 BOOL is DWORD. You can define pvData as ref UInt32
or ref Int32
for this case. Or leave pvData as IntPtr, allocate unmanaged memory with Marshal.AllocHGLobal(Marshal.SizeOf(Int32))
, and fill this memory with Marshal.WriteInt32
.
int size = Marshal.SizeOf(Int32); IntPtr pBool = Marshal.AllocHGlobal(size); Marshal.WriteInt32(pBool, 0, 1); // last parameter 0 (FALSE), 1 (TRUE) /* use the IntPtr */ Marshal.FreeHGlobal(pBool);
Oh, yes, there's a much easier way. This can be very elegantly done in C# because it supports method overloading. A feature that doesn't exist in C and thus requires the PVOID argument type. You can simply declare the argument as ref bool
. The marshaller will create the storage for the BOOL before calling the native function and pass a pointer to it. Converting and copying the result back into the bool variable you pass after the call.
If you have additional calls for this function that require a different data type then just repeat the declaration. This time specifying, say, ref uint
if you are supposed to pass a pointer to a DWORD. Etcetera. The C# compiler's method overload resolution feature ensures that the correct pinvoke declaration is used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With