「ネイティブWiFi API」Windows APIの使用方法Delphiで機能します
質問
DelphiでWindows APIの関数を使用しようとしているのは、Windows wlanapi.dll(ネイティブ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
);
私はこの機能や他の人を何時間も使用しようとしており、MSDN参照や他のサイトを読んでいますが、これを機能させることはできません。
私の試み
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;
私はこのAPIを翻訳しようとしています、多くの仕事のようです、そして私はDelphiの初心者です、私はウェブ上でたくさんのものを読みました、私はこれにどのように対処しますか OpCode
パラメーターは、定数を持つC構造体とpwlan_opcode_value_typeのようです。
http://msdn.microsoft.com/en-us/library/windows/desktop/dd439502(v=vs.85).aspx
解決
あなたは実際にあなたがどのように呼んだかを示していませんでした apiWlanOpenHandle
これは、問題が何であるかを説明すると思います。しかし、あなたを混乱させている可能性が最も高い非常に一般的な間違いが1つあります。
APIのC宣言を考えてみましょう。
DWORD WINAPI WlanOpenHandle(
__in DWORD dwClientVersion,
__reserved PVOID pReserved,
__out PDWORD pdwNegotiatedVersion,
__out PHANDLE phClientHandle
);
私があなたの問題を引き起こしていると思われるパラメーターは、最後の2つです。よく考えさせてください pdwNegotiatedVersion
. 。これはaへのポインターです DWORD
. 。これはOUTパラメーターであるため、有効なメモリへのポインターを提供する必要があります。私はあなたがタイプの変数を宣言しているだけだと思います PDWORD
そしてそれを渡します。
var
NegotiatedVersionPtr: PDWORD;
begin
WlanOpenHandle(...., NegotiatedVersionPtr, ...);
関数 WlanOpenHandle
次に、そのポインターを参照し、記憶に書き込もうとします。有効なポインターを与えていない場合、これは失敗します。
素朴な解決策は、呼び出しコードを変更して次のように見えることです。
var
NegotiatedVersion: DWORD;
NegotiatedVersionPtr: PDWORD;
begin
NegotiatedVersionPtr := @NegotiatedVersion;
WlanOpenHandle(...., NegotiatedVersionPtr, ...);
これは機能しますが、よりクリーンな方法があります。このようなAPIインポートを宣言します:
function WlanOpenHandle(
dwClientVersion: DWORD;
pReserved: Pointer;
out NegotiatedVersion: DWORD;
out ClientHandle: THandle
): DWORD; stdcall; external 'Wlanapi.dll';
an out
タイプのパラメーター DWORD
実際にはポインターとして渡されます DWORD
関数呼び出しの引数として提供すること。次に、呼び出しコードを変更して次のようになります。
var
ReturnValue: DWORD;
NegotiatedVersion: DWORD;
ClientHandle: THandle;
begin
ReturnValue := WlanOpenHandle(2, nil, NegotiatedVersion, ClientHandle);
if ReturnValue<>ERROR_SUCCESS then
//respond to error
また、実際にすべきエラーチェックを追加したことに注意してください。
Windows API関数がポインターを使用して宣言されている理由は、C言語が値で通過するパラメーターのみをサポートするためです。単にパスごとに参照されていません out
また var
Delphiの用語で。パスバイレファレンスをサポートする言語は、可能な限りそれらを利用する必要があります。
一部のWindows API関数には、ポインターとして宣言されたオプションのパラメーターがあります。これが渡された場合 NULL
ポインターは、パラメーターを渡したくないことを示す方法です。これらのAPIをDelphiに翻訳することはより複雑です。ポインターを使用してバージョンを実装して、発信者がパラメーターの提供をオプトアウトできるようにする必要があります。しかし、使用する過負荷バージョンを提供することは役立ちます out
また var
発信者に便利です。デルフィ Windows
ユニットには多くのそのような例が含まれています。
はどうかと言うと WlanHostedNetworkQueryProperty
, 、私はそれをこのように宣言します:
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;
私は使用しました delayed
施設これはWindows 7以降のAPIであるためです。おそらく、プログラムが古いバージョンのWindowsで実行されるため、読み込みを遅らせる必要があります。 Delphiの遅延荷重の詳細については、 この答え, 、、特に以前のリンク。
リンクするMSDNトピックのドキュメントは間違っていることに注意してください。 pWlanOpcodeValueType
パラメーターは、MSDNトピックで誤って宣言されます。正しい定義、で見つかるもの wlanpi.h
これは:
__out PWLAN_OPCODE_VALUE_TYPE pWlanOpcodeValueType,