Как использовать функции API «Натив Wi -Fi API» с Delphi

StackOverflow https://stackoverflow.com/questions/9344980

  •  27-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь использовать функцию из Windows API на Delphi, функции для Windows wlanapi.dll (Native 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, я много читал в Интернете, как мне справиться с этим OpCode Параметр, кажется, C -структуру с константами и pwlan_opcode_value_type?

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

Это было полезно?

Решение

Ты на самом деле не показал, как ты позвонил 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

Обратите внимание, что я также добавил некоторую проверку ошибок, которую вы действительно должны делать.

Причина, по которой функция API Windows объявляется с использованием указателей, заключается в том, что язык C поддерживает только параметр, проходящий по значению. Это просто не имеет прохождения, т.е. out или же var в терминах Delphi. Языки, которые поддерживают пропущенные ссылки, должны использовать их, когда могут.

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

Обратите внимание, что документация в теме MSDN, на которую вы ссылка неверна. А pWlanOpcodeValueType Параметр неверно объявляется в теме MSDN. Правильное определение, которое можно найти в wlanpi.h это:

__out    PWLAN_OPCODE_VALUE_TYPE     pWlanOpcodeValueType,
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top