So verwenden Sie "native WiFi -API" -Funktionen mit Delphi Windows -API -Funktionen
Frage
Ich versuche, eine Funktion von Windows API auf Delphi zu verwenden, Funktionen für 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
);
Ich versuche, diese und andere Funktionen stundenlang zu verwenden und die MSDN -Referenzen und andere Websites zu lesen, aber ich kann dies einfach nicht zum Laufen bringen.
Mein Versuch
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;
Ich versuche, diese API zu übersetzen, scheint viel Arbeit zu sein, und ich bin nur ein Anfänger in Delphi. Ich habe viele Dinge im Web gelesen, wie gehe ich damit um OpCode
Parameter, scheint eine C -Struktur mit Konstanten und pwlan_opcode_value_type?
http://msdn.microsoft.com/en-us/library/windows/desktop/dd439502(v=vs.85).aspx
Lösung
Sie haben nicht wirklich gezeigt, wie Sie angerufen haben apiWlanOpenHandle
Was, denke ich, erklären, was das Problem ist. Es gibt jedoch einen sehr häufigen Fehler, der Sie höchstwahrscheinlich verwirrt.
Betrachten Sie die C -Erklärung der API:
DWORD WINAPI WlanOpenHandle(
__in DWORD dwClientVersion,
__reserved PVOID pReserved,
__out PDWORD pdwNegotiatedVersion,
__out PHANDLE phClientHandle
);
Die Parameter, von denen ich vermute, dass sie Ihnen Probleme verursachen, sind die letzten beiden. Lass uns in Erwägung ziehen pdwNegotiatedVersion
. Dies ist ein Zeiger auf a DWORD
. Da dies ein Out -Parameter ist, müssen Sie einen Zeiger für den gültigen Speicher angeben. Ich vermute, Sie deklarieren nur eine Variable des Typs PDWORD
und das vorbei.
var
NegotiatedVersionPtr: PDWORD;
begin
WlanOpenHandle(...., NegotiatedVersionPtr, ...);
Die Funktion WlanOpenHandle
Dann entlarvt, dass Zeiger und versucht, in die Erinnerung zu schreiben. Wenn Sie keinen gültigen Zeiger gegeben haben, schlägt dies fehl.
Die naive Lösung besteht darin, den Aufrufcode so zu ändern, dass er so aussieht:
var
NegotiatedVersion: DWORD;
NegotiatedVersionPtr: PDWORD;
begin
NegotiatedVersionPtr := @NegotiatedVersion;
WlanOpenHandle(...., NegotiatedVersionPtr, ...);
Dies wird funktionieren, aber es gibt einen viel saubereren Weg. Erklären Sie die API -Import so:
function WlanOpenHandle(
dwClientVersion: DWORD;
pReserved: Pointer;
out NegotiatedVersion: DWORD;
out ClientHandle: THandle
): DWORD; stdcall; external 'Wlanapi.dll';
Ein out
Parameter des Typs DWORD
wird tatsächlich als Zeiger auf die DWORD
dass Sie als Argument für den Funktionsaufruf liefern. Sie können dann Ihren Anrufcode ändern, um so auszusehen:
var
ReturnValue: DWORD;
NegotiatedVersion: DWORD;
ClientHandle: THandle;
begin
ReturnValue := WlanOpenHandle(2, nil, NegotiatedVersion, ClientHandle);
if ReturnValue<>ERROR_SUCCESS then
//respond to error
Beachten Sie, dass ich auch einige Fehlerprüfung hinzugefügt habe, die Sie wirklich tun sollten.
Der Grund, warum die Windows -API -Funktion unter Verwendung von Zeigern deklariert wird, ist, dass die C -Sprache nur den Parameter unterstützt. Es hat einfach keine Pass-by-Referenz, dh out
oder var
in Delphi. Sprachen, die Pass-by-Reference unterstützen, sollten sie verwenden, wenn sie können.
Einige Windows -API -Funktionen haben optionale Parameter, die als Zeiger deklariert sind. Wenn dies der Fall ist, vergeht NULL
Da der Zeiger der Weg ist, um zu signalisieren, dass Sie keinen Parameter übergeben möchten. Das Übersetzen dieser APIs in Delphi ist komplexer. Sie müssen eine Version verwenden, um Zeiger zu verwenden, damit Anrufer die Lieferung des Parameters abmelden können. Es kann jedoch hilfreich sein, eine überlastete Version zu liefern, die verwendet out
oder var
zur Bequemlichkeit des Anrufers. Der Delphi Windows
Die Einheit enthält viele solche Beispiele.
Wie für WlanHostedNetworkQueryProperty
, Ich würde es so erklären:
const
// WLAN_HOSTED_NETWORK_OPCODE constants
wlan_hosted_network_opcode_connection_settings = 0;
wlan_hosted_network_opcode_security_settings = 1;
wlan_hosted_network_opcode_station_profile = 2;
wlan_hosted_network_opcode_enable = 3;
// WLAN_OPCODE_VALUE_TYPE constants
wlan_opcode_value_type_query_only = 0;
wlan_opcode_value_type_set_by_group_policy = 1;
wlan_opcode_value_type_set_by_user = 2;
wlan_opcode_value_type_invalid = 3;
function WlanHostedNetworkQueryProperty(
hClientHandle: THandle;
OpCode: Integer;
out DataSize: DWORD;
out Data: Pointer;
out WlanOpcodeValueType: Integer;
Reserved: Pointer
): DWORD; external 'Wlanapi.dll' delayed;
Ich habe das benutzt delayed
Einrichtung, weil dies eine API von Windows 7 und Up ist. Sie werden vermutlich möchten, dass Ihr Programm auf älteren Windows -Versionen ausgeführt wird, und daher ist die Verzögerung des Ladens erforderlich. Weitere Informationen zum Verzögerungsladen in Delphi finden Sie unter Diese Antwort, und insbesondere die weiteren Links.
Beachten Sie, dass die Dokumentation im MSDN -Thema, mit dem Sie verlinken, falsch ist. Das pWlanOpcodeValueType
Der Parameter wird im MSDN -Thema falsch deklariert. Die richtige Definition, die in der gefunden werden wlanpi.h
ist das:
__out PWLAN_OPCODE_VALUE_TYPE pWlanOpcodeValueType,