Im trying to use a function from Windows API on delphi, functions for Windows Wlanapi.dll (Native WIFI API)
DWORD WINAPI WlanOpenHandle(
__in DWORD dwClientVersion,
__reserved PVOID pReserved,
__out PDWORD pdwNegotiatedVersion,
__out PHANDLE phClientHandle
);
WlanHostedNetworkQueryProperty
DWORD WINAPI WlanHostedNetworkQueryProperty(
__in HANDLE hClientHandle,
__in WLAN_HOSTED_NETWORK_OPCODE OpCode,
__out PDWORD pdwDataSize,
__out PVOID *ppvData,
__out PWLAN_OPCODE_VALUE_TYPE *pWlanOpcodeValueType,
__reserved PVOID pvReserved
);
I trying to use this functions and others for hours, reading the MSDN references and others sites, but I just can't get this working.
My attempt
type
TWlanOpenHandle = function( dwClientVersion:DWORD;
pReserved:Pointer;
pdwNegotiatedVersion:PDWORD;
phClientHandle:PHANDLE
):DWORD; stdcall;
function apiWlanOpenHandle( dwClientVersion:DWORD;
pReserved:Pointer;
pdwNegotiatedVersion:PDWORD;
phClientHandle:PHANDLE
):DWORD;
implementation
function apiWlanOpenHandle ( dwClientVersion:DWORD; pReserved:Pointer; pdwNegotiatedVersion:PDWORD; phClientHandle:PHANDLE ):DWORD;
var
WlanOpenHandle: TWlanOpenHandle;
DLL: Cardinal;
begin
DLL:=LoadLibrary('Wlanapi.dll');
WlanOpenHandle := GetProcAddress(DLL, 'WlanOpenHandle');
if Assigned(WlanOpenHandle) then
begin
WlanOpenHandle(dwClientVersion, pReserved, pdwNegotiatedVersion, phClientHandle);
end
else begin
ShowMessage('Function not found');
end;
end;
I'm trying to translate this API, seems a lot of work, and I'm just a beginner in delphi, I read a lot of stuff on the web, how do I deal with this OpCode
parameter, seems a C Struct with constants, and PWLAN_OPCODE_VALUE_TYPE?
http://msdn.microsoft.com/en-us/library/windows/desktop/dd439502(v=vs.85).aspx
You didn't actually show how you called
apiWlanOpenHandle
which would, I think, explain what the problem is. However, there's one very common mistake that is most likely what is confusing you.Consider the C declaration of the API:
The parameters that I suspect are causing you problems are the final two. Let us consider
pdwNegotiatedVersion
. This is a pointer to aDWORD
. Because this is an out parameter you must supply a pointer to valid memory. I suspect you are just declaring a variable of typePDWORD
and passing that.The function
WlanOpenHandle
then de-references that pointer and tries to write to the memory. If you have not given a valid pointer then this will fail.The naive solution is to change the calling code to look like this:
This will work but there is a much cleaner way. Declare the API import like this:
An
out
parameter of typeDWORD
is actually passed as a pointer to theDWORD
that you supply as the argument to the function call. You can then change your calling code to look like this:Note that I have also added some error checking which you really ought to be doing.
The reason that the Windows API function is declared using pointers is that the C language only supports parameter passing by value. It simply does not have pass-by-reference, i.e.
out
orvar
in Delphi terms. Languages that do support pass-by-reference should make use of them when they can.Some Windows API functions have optional parameters declared as pointers. When this is the case passing
NULL
as the pointer is the way to signal that you do not wish to pass a parameter. Translating those APIs to Delphi is more complex. You need to implement a version using pointers to allow callers to opt-out of supplying the parameter. But it can be helpful to supply an overloaded version that usesout
orvar
for convenience to the caller. The DelphiWindows
unit contains many such examples.As for
WlanHostedNetworkQueryProperty
, I would declare it like this:I have used the
delayed
facility because this is a Windows 7 and up API. You will presumably want your program to run on older versions of Windows and so delay loading is needed. For more information on delay loading in Delphi, see this answer, and particularly the onward links.Note that the documentation in the MSDN topic to which you link is incorrect. The
pWlanOpcodeValueType
parameter is declared incorrectly in the MSDN topic. The correct definition, the one to be found inwlanpi.h
is this: