2012-02-18 20 views
4

イムデルファイ上のWindows APIから機能を使用しようと、"ネイティブ無線LAN API" DelphiでWindows API関数を使用する方法

WlanOpenHandle

DWORD WINAPI WlanOpenHandle(
    __in  DWORD dwClientVersion, 
    __reserved PVOID pReserved, 
    __out  PDWORD pdwNegotiatedVersion, 
    __out  PHANDLE phClientHandle 
); 
のWindows Wlanapi.dll(ネイティブWIFIのAPI)のための機能

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の参照と他のサイトを読んで、時間のためにこの機能などを使用しようとしているが、私はちょうどこのワーキンを取得することはできませんg。

私はこのAPIを翻訳しようとしている

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; 

私の試みは、多くの作業をようで、私はDelphiでちょうど初心者だけど、私はウェブ上で多くのものを読んで、どのように行います私はこのOpCodeのパラメータを扱い、定数を持つC Structと思われ、PWLAN_OPCODE_VALUE_TYPE?

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

+2

正確に何か問題がありますか? DLL関数をロードするコードを示しましたが、実際にそれを使用しようとしているコードは表示されませんでした。 –

+0

なぜホイールを再発明するか。それは完了しました:http://theroadtodelphi.wordpress.com/2009/10/07/detecting-wifi-networks-using-delphi/ –

+0

@WarrenP仕事ははるかに少ないでしょうが、これは時代遅れです、私が必要とする機能はWlanHostedNetwork ... Windows 7またはWindows 2008のこのlibを知っていれば教えてください。どうもありがとうございます。 –

答えて

12

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

は、APIのC宣言を考えてみましょう:

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

私はあなたの問題を引き起こしている疑いがあるパラメータ最後の2つです。我々はpdwNegotiatedVersionを考えてみましょう。これはDWORDへのポインタです。これはoutパラメータであるため、有効なメモリへのポインタを指定する必要があります。私はちょうどタイプPDWORDの変数を宣言し、それを渡していると思う。メモリへの書き込みをしようとポインタと

var 
    NegotiatedVersionPtr: PDWORD; 
begin 
    WlanOpenHandle(...., NegotiatedVersionPtr, ...); 

機能WlanOpenHandle次いで脱参照。有効なポインタを与えていなければ、これは失敗します。

素朴な解決策は次のように見えるように、呼び出し元のコードを変更することです:

var 
    NegotiatedVersion: DWORD; 
    NegotiatedVersionPtr: PDWORD; 
begin 
    NegotiatedVersionPtr := @NegotiatedVersion; 
    WlanOpenHandle(...., NegotiatedVersionPtr, ...); 

これは動作しますが、非常にきれいな方法があります。タイプDWORD

function WlanOpenHandle(
    dwClientVersion: DWORD; 
    pReserved: Pointer; 
    out NegotiatedVersion: DWORD; 
    out ClientHandle: THandle 
): DWORD; stdcall; external 'Wlanapi.dll'; 

outパラメータは実際には関数呼び出しの引数として供給DWORDへのポインタとして渡されます。このようなAPIのインポートを宣言します。呼び出しコードを次のように変更することができます。

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)はありません。参照渡しをサポートする言語では、可能な限り使用する必要があります。

一部のWindows API関数には、ポインタとして宣言されたオプションのパラメータがあります。これがケースの場合、ポインターとしてNULLを渡すことは、パラメーターを渡すことを望まないことを伝える方法です。これらのAPIをDelphiに翻訳するのはもっと複雑です。呼び出し元がパラメータの入力をオプトアウトできるようにするには、ポインタを使用してバージョンを実装する必要があります。しかし、呼び出し側の便宜のためにoutまたはvarを使用するオーバーロードされたバージョンを提供すると便利です。 Delphi Windowsユニットには、このような例が多数あります。


WlanHostedNetworkQueryPropertyについては、私はこのように宣言します:これは、Windows 7およびAPI次第ですので、私はdelayed施設を使用していた

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; 

。おそらくあなたのプログラムは古いバージョンのWindows上で動作するようになり、遅延ロードが必要になるでしょう。 Delphiでの遅延ロードの詳細については、this answerを参照してください。特に後続のリンクを参照してください。

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

__out PWLAN_OPCODE_VALUE_TYPE  pWlanOpcodeValueType, 
+0

+1を占めるようにします。良い情報。 –

+0

ありがとう、私はこれを手伝ってhttp://vitim.us/test/Convert_C_to_Delphi.htmを書いています。これは魔法のようにすべてを解決するのではなく、仕事を減らすことです。 –

+0

私は別の問題を抱えている可能性があります。この他の機能http://msdn.microsoft.com/en-us/library/windows/desktop/dd439491(v=vs.85).aspx、どうすれば対処できますか?このパラメータはデフォルトの型ではなく、このtypedef C Structです。私は記録として宣言できますか? –

関連する問題