Перевод заголовка Vista WinAPI C ++ для Delphi - есть предложения? - PullRequest
3 голосов
/ 17 июня 2009

Мне нужно вызвать функцию Windows API, представленную в Vista, из моего приложения Delphi, но у меня нет заголовков Delphi, описывающих эту функцию.

Связанные функции уже задокументированы в библиотеке API JEDI Windows, но не в этой функции.

Мой C ++ почти не существует, и я изо всех сил пытаюсь выработать определения Delphi, которые соответствуют функции и ее параметру, как описано в MSDN.

С http://msdn.microsoft.com/en-us/library/aa814417.aspx

NETIOAPI_API GetIpInterfaceEntry(__inout  PMIB_IPINTERFACE_ROW Row);

typedef struct _MIB_IPINTERFACE_ROW {
  ADDRESS_FAMILY                 Family;
  NET_LUID                       InterfaceLuid;
  NET_IFINDEX                    InterfaceIndex;
  ULONG                          MaxReassemblySize;
  ULONG64                        InterfaceIdentifier;
  ULONG                          MinRouterAdvertisementInterval;
  ULONG                          MaxRouterAdvertisementInterval;
  BOOLEAN                        AdvertisingEnabled;
  BOOLEAN                        ForwardingEnabled;
  BOOLEAN                        WeakHostSend;
  BOOLEAN                        WeakHostReceive;
  BOOLEAN                        UseAutomaticMetric;
  BOOLEAN                        UseNeighborUnreachabilityDetection;
  BOOLEAN                        ManagedAddressConfigurationSupported;
  BOOLEAN                        OtherStatefulConfigurationSupported;
  BOOLEAN                        AdvertiseDefaultRoute;
  NL_ROUTER_DISCOVERY_BEHAVIOR   RouterDiscoveryBehavior;
  ULONG                          DadTransmits;
  ULONG                          BaseReachableTime;
  ULONG                          RetransmitTime;
  ULONG                          PathMtuDiscoveryTimeout;
  NL_LINK_LOCAL_ADDRESS_BEHAVIOR LinkLocalAddressBehavior;
  ULONG                          LinkLocalAddressTimeout;
  ULONG                          ZoneIndices[ScopeLevelCount];
  ULONG                          SitePrefixLength;
  ULONG                          Metric;
  ULONG                          NlMtu;
  BOOLEAN                        Connected;
  BOOLEAN                        SupportsWakeUpPatterns;
  BOOLEAN                        SupportsNeighborDiscovery;
  BOOLEAN                        SupportsRouterDiscovery;
  ULONG                          ReachableTime;
  NL_INTERFACE_OFFLOAD_ROD       TransmitOffload;
  NL_INTERFACE_OFFLOAD_ROD       ReceiveOffload;
  BOOLEAN                        DisableDefaultRoutes;
}MIB_IPINTERFACE_ROW, *PMIB_IPINTERFACE_ROW;

Среди других битов бит, с которым я сейчас борюсь, это поле ZoneIndices [ScopeLevelCount]; Я не могу понять, какого размера должен быть массив.

Это то, что я определил до сих пор, хотя я еще не определил перечисления в исходном определении C ++. Я буду явно загружать Windows DLL в Vista и получать адрес новой функции для вызова.

type
  PMIB_IPINTERFACE_ROW = ^MIB_IPINTERFACE_ROW;
  {$EXTERNALSYM PMIB_IPINTERFACE_ROW}
  _MIB_IPINTERFACE_ROW = record
    Family: ADDRESS_FAMILY;
    InterfaceLuid: NET_LUID;
    InterfaceIndex: NET_IFINDEX;
    MaxReassemblySize,
    InterfaceIdentifier,
    MinRouterAdvertisementInterval,
    MaxRouterAdvertisementInterval: Cardinal;
    AdvertisingEnabled,
    ForwardingEnabled,
    WeakHostSend,
    WeakHostReceive,
    UseAutomaticMetric,
    UseNeighborUnreachabilityDetection,
    ManagedAddressConfigurationSupported,
    OtherStatefulConfigurationSupported,
    AdvertiseDefaultRoute: LongBool;
    RouterDiscoveryBehavior: NL_ROUTER_DISCOVERY_BEHAVIOR;
    DadTransmits,
    BaseReachableTime,
    RetransmitTime,
    PathMtuDiscoveryTimeout: Cardinal;
    LinkLocalAddressBehavior: NL_LINK_LOCAL_ADDRESS_BEHAVIOR;
    LinkLocalAddressTimeout,
    ZoneIndices[ScopeLevelCount],
    SitePrefixLength,
    Metric,
    NlMtu: Cardinal;
    Connected,
    SupportsWakeUpPatterns,
    SupportsNeighborDiscovery,
    SupportsRouterDiscovery: LongBool;
    ReachableTime: Cardinal;
    TransmitOffload: NL_INTERFACE_OFFLOAD_ROD;
    ReceiveOffload: NL_INTERFACE_OFFLOAD_ROD;
    DisableDefaultRoutes: LongBool;
  end;
  {$EXTERNALSYM _MIB_IPINTERFACE_ROW}
  MIB_IPINTERFACE_ROW = _MIB_IPINTERFACE_ROW;
  {$EXTERNALSYM MIB_IPINTERFACE_ROW}
  TMibIpInterfaceRow = MIB_IPINTERFACE_ROW;
  PMibIpInterfaceRow = PMIB_IPINTERFACE_ROW;

const
  iphlpapilib = 'iphlpapi.dll';

var
  HIpHlpApi: THandle = 0;
  GetIpInterfaceEntry: function(const pArpEntry: MIB_IPINTERFACE_ROW): LongInt; stdcall;
  {$EXTERNALSYM GetIpInterfaceEntry}

Есть ли у кого-нибудь предложения или советы / рекомендации по переводу определения функции, подобного этому?

Большое спасибо,

Конор

Ответы [ 8 ]

2 голосов
/ 17 июня 2009

Тип Win32 BOOLEAN - один байт, а тип Delphi LongBool - четыре. Вместо этого используйте Delphi's ByteBool.

1 голос
/ 18 июня 2009

Массив ZoneIndices должен быть определен так:

ZoneIndices : array [0..ScopeLevelCount - 1] of Cardinal;

ScopeLevelCount - это константа, равная 16

1 голос
/ 17 июня 2009

Убедитесь, что вы используете упакованную команду при определении своей записи, потому что Delphi выравнивает сложные типы данных по 2, 4 или 8 байтовым границам по умолчанию.

TExample = record 
 f1: Integer;   // start at offset 0x00
 f2: Char;      // start at offset 0x04 
 f3: Integer;   // start at offset 0x06 or 0x08 depending on alignment
end;

TExample = packed record // this is what c++ would do
 f1: Integer;   // start at offset 0x00
 f2: Char;      // start at offset 0x04 
 f3: Integer;   // start at offset 0x05
end;
1 голос
/ 17 июня 2009

Я часто использовал Доктор. Конвертер заголовков Боба для этой задачи, но в основном я выбрал долгий и утомительный способ ручного выполнения преобразования, потому что это помогло мне лучше понять API. (Потому что я собирался его использовать, и мне все равно нужно с ним ознакомиться)

Также смотрите эту статью: http://www.delphi -jedi.org / api-howto.html

В общем, лучше не возлагать больших надежд на инструмент преобразования заголовков, потому что C ++ - очень мощный и сложный язык. Большинство протестированных мной инструментов преобразования поддерживают только подмножество C ++ и его препроцессор, что делает необходимым ручное исправление сгенерированного источника.

1 голос
/ 17 июня 2009

Может быть, вы можете попробовать "C 2 pas"

Также найдены следующие инструменты:

1 голос
/ 17 июня 2009

Хм. Странная структура. Но если вы загляните в w2def.h, вы увидите, что ScopeLevelCount = 16. Таким образом, ваш массив должен иметь 16 элементов,

0 голосов
/ 18 июня 2009

Я не вижу ни одного поля типа ULONG64 в переводе, но я вижу в оригинале.

Кроме того, FPC также имеет конвертер заголовков, который отлично работает для структур. Как правило, окна api структуры упакованы.

В случае сомнений, используйте какой-нибудь бесплатный продукт msvc, чтобы написать sizeof (структуру), и сделайте то же самое в паскале Если это соответствует, и у вас все еще есть сомнения, рассчитайте смещения полей с небольшим количеством волшебства указателя и сравните их.

0 голосов
/ 17 июня 2009

вы можете исследовать некоторые уже переведенные API / структуры, связанные с этим предметом, и конвертировать его самостоятельно. например этот

...