4

DelphiでWindows APIの関数、Windows Wlanapi.dll(ネイティブWIFI API)の関数を使用しようとしています

WlanOpenHandle

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 の初心者です。Web で多くのことを読みました。このOpCodeパラメーターをどのように処理すればよいでしょうか。定数を持つ C 構造体のようです。および PWLAN_OPCODE_VALUE_TYPE?

http://msdn.microsoft.com/en-us/library/windows/desktop/dd439502(v=vs.85).aspx

4

1 に答える 1

14

あなたは実際にあなたがどのように電話したかを示していませんでしたapiWlanOpenHandle、私は、問題が何であるかを説明すると思います。ただし、非常によくある間違いが1つあります。これは、混乱を招く可能性が最も高いものです。

APIのC宣言について考えてみましょう。

DWORD WINAPI WlanOpenHandle(
  __in        DWORD dwClientVersion,
  __reserved  PVOID pReserved,
  __out       PDWORD pdwNegotiatedVersion,
  __out       PHANDLE phClientHandle
);

問題を引き起こしていると思われるパラメーターは、最後の2つです。考えてみましょうpdwNegotiatedVersion。これはへのポインタDWORDです。これは出力パラメータであるため、有効なメモリへのポインタを指定する必要があります。型の変数を宣言して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';

タイプの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言語が値によるパラメータの受け渡しのみをサポートしているためです。参照渡し、つまりDelphiの用語は含まれていませoutvar。参照渡しをサポートする言語は、可能な場合はそれらを使用する必要があります。

一部のWindowsAPI関数には、ポインタとして宣言されたオプションのパラメータがあります。これがケースパスである場合NULL、ポインタはパラメータを渡したくないことを通知する方法です。これらのAPIをDelphiに変換するのはもっと複雑です。呼び出し元がパラメーターの提供をオプトアウトできるようにするには、ポインターを使用してバージョンを実装する必要があります。outただし、呼び出し元を使用する、またはvar呼び出し元の便宜のために、オーバーロードされたバージョンを提供すると役立つ場合があります。DelphiWindowsユニットにはそのような例がたくさん含まれています。


に関しては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これはWindows7以降のAPIであるため、この機能を使用しました。おそらく、プログラムを古いバージョンのWindowsで実行する必要があるため、読み込みを遅らせる必要があります。Delphiでの遅延ロードの詳細については、この回答、特に以降のリンクを参照してください。

リンク先のMSDNトピックのドキュメントが正しくないことに注意してください。このpWlanOpcodeValueTypeパラメーターは、MSDNトピックで誤って宣言されています。正しい定義、で見つかるものwlanpi.hはこれです:

__out    PWLAN_OPCODE_VALUE_TYPE     pWlanOpcodeValueType,
于 2012-02-18T23:19:22.230 に答える