2012-02-18 5 views
4

Im пытается использовать функцию из Windows API на Дельфи, функции для Windows, Wlanapi.dll (Native API) WIFIКак использовать "Native Wi-Fi API" функции Windows API, с Delphi

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 референции и другие сайты, но я просто не могу получить эту Workin г.

Моя попытка

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, кажется, много работы, и я просто новичок в Дельфах, я прочитал много материала в Интернете, как сделать Я рассматриваю этот параметр 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 или 2008, пожалуйста, скажите мне, спасибо вам в любом случае. –

ответ

12

Вы не на самом деле показать, как вы назвали apiWlanOpenHandle которая, как мне кажется, объяснить, в чем проблема. Однако есть одна очень распространенная ошибка, которая, скорее всего, вас сбивает с толку.

Рассмотрим декларацию C в API:

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

Параметры, которые я подозреваю, вызывают вас проблемы являются окончательными два. Рассмотрим pdwNegotiatedVersion. Это указатель на 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'; 

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. Языки, которые поддерживают передачу по ссылке, должны использовать их, когда они могут.

Некоторые функции API Windows имеют необязательные параметры, объявленные как указатели. Если это так, то передайте NULL, поскольку указатель - это способ сообщить, что вы не хотите передавать параметр. Перевод этих API в Delphi более сложный. Вам нужно реализовать версию с помощью указателей, чтобы позволить абонентам отказаться от подачи параметра. Но может быть полезно предоставить перегруженную версию, которая использует out или var для удобства вызывающего абонента. Блок 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. Хорошая информация. –

+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. Я могу заявить как запись? –

 Смежные вопросы

  • Нет связанных вопросов^_^