2012-02-18 95 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