2012-02-18 92 views
4

我試着去Delphi的使用功能從Windows API,爲Windows Wlanapi.dll(本機WIFI API)如何使用 「本地WiFi API」 用Delphi的Windows 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和其他網站,但我不能得到這個幹活G。

我嘗試

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

+2

究竟是什麼問題?你展示了加載DLL函數的代碼,但沒有試圖實際使用它的代碼。 – 2012-02-18 23:07:35

+0

爲什麼要重新發明車輪。它已經完成:http://theroadtodelphi.wordpress.com/2009/10/07/detecting-wifi-networks-using-delphi/ – 2012-02-19 02:37:36

+0

@WarrenP會少得多的工作,但這是過時的,我需要的功能是缺少WlanHostedNetwork ...如果你知道Windows 7或2008的這個lib,請告訴我,謝謝你。 – 2012-02-19 05:42:39

回答

12

你實際上並沒有告訴你怎麼叫apiWlanOpenHandle這會,我想,解釋一下是什麼問題。但是,有一個非常常見的錯誤很可能使您感到困惑。

考慮API的C聲明:

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

,我懷疑是導致問題的參數是最後兩個。讓我們考慮一下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'; 

DWORD類型的out參數實際上是作爲指針你提供的作爲參數傳遞給函數調用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語言只支持按值傳遞參數。它沒有通過引用,即德爾菲術語中的outvar。支持通過引用的語言應儘可能使用它們。

某些Windows API函數具有聲明爲指針的可選參數。當這種情況通過NULL時,指針是指示您不希望傳遞參數的方式。將這些API轉換爲Delphi更爲複雜。您需要使用指針實現版本,以允許調用者選擇不提供參數。但爲方便調用者提供使用outvar的重載版本可能會有幫助。 Delphi 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中延遲加載的更多信息,請參閱this answer,尤其是前面的鏈接。

請注意您鏈接到的MSDN主題中的文檔不正確。 pWlanOpcodeValueType參數在MSDN主題中聲明不正確。正確的定義,在wlanpi.h中找到的是這樣的:

__out PWLAN_OPCODE_VALUE_TYPE  pWlanOpcodeValueType, 
+0

+1。良好的信息。 – 2012-02-19 02:42:51

+0

謝謝,我寫了這個幫助我http://vitim.us/test/Convert_C_to_Delphi.htm這不是神奇地解決整個事情,但只是減少我的工作。 – 2012-02-19 05:39:27

+0

我有另一個問題,也許你可以幫助我,這個其他功能http://msdn.microsoft.com/en-us/library/windows/desktop/dd439491(v=vs.85).aspx,我該如何處理這個參數不是默認的類型,這個typedef C Struct。我可以聲明爲記錄? – 2012-02-19 05:46:12