Reputation: 1034
I'm needing to call a Windows API function introduced in Vista from my Delphi app, but I don't have any Delphi headers which describe the function.
Related functions are already documented in the JEDI Windows API library, but not this function.
My C++ is almost non-existent, and I'm struggling to work out the Delphi definitions that correspond to the function and it's parameter as documented on MSDN.
From 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;
Among other bits, the bit I'm struggling with at the minute is the ZoneIndices[ScopeLevelCount] field; I can't work out what size the array is supposed to be.
This is what I've defined so far, although I haven't worked out the enums in the original C++ definition yet. I'll be explicitly loading the Windows DLL on Vista and getting the address of the new function to call.
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}
Does anybody out there have suggestions or tips/tricks for translating a function definition like this?
Many thanks,
Conor
Upvotes: 3
Views: 1388
Reputation: 26376
I don't see any field of type ULONG64 in the translation, but I do in the original.
Further, FPC also has an header converter which works fine for structs. Typically windows api structures are packed.
In doubt, use some free msvc product to write the sizeof(structure) and do the same under pascal. If that matches, and you still have doubts, calculate field offsets with a bit of pointer magic and compare them.
Upvotes: 0
Reputation: 72514
I often used Dr. Bob's Header Converter for this task, but mostly I took the long and tedious way of manually performing the conversion, because it helped me to understand the API better. (Because I was going to use it and I have to familiarize myself with it anyway)
Also see this article: http://www.delphi-jedi.org/api-howto.html
In general it's best not to put to much hopes on a header conversion tool, because C++ is a very powerful and complex language. Most conversion tools I tested only supported a subset of C++ and its preprocessor, thus making it necessary to manually make fixes to the generated source.
Upvotes: 1
Reputation: 2474
The ZoneIndices array should be defined like this:
ZoneIndices : array [0..ScopeLevelCount - 1] of Cardinal;
ScopeLevelCount
is a constant that is 16
Upvotes: 1
Reputation: 163317
The Win32 BOOLEAN
type is one byte, but Delphi's LongBool
type is four. Use Delphi's ByteBool
instead.
Upvotes: 2
Reputation: 33302
Make sure you use the packed command when defining your record because Delphi aligns complex data types on 2, 4 or 8 byte boundaries by default.
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;
Upvotes: 1
Reputation:
Hmm. A strange structore. But if you look into w2def.h, you can see that ScopeLevelCount=16. So your array should have 16 elements,
Upvotes: 1
Reputation: 1180
you can investigate some already translated APIs/structures that related to this subject and convert it yourself. for example this one
Upvotes: 0
Reputation: 9112
Maybe you can try "C 2 pas"
Also found these tools:
Upvotes: 1