私は最終的に弾丸をかみ、XE6 を購入しました。したがって、この単純な Windows API 呼び出しが失敗する理由を誰かが教えてくれれば、非常にありがたいです。この関数はエラーを返しません。最初の呼び出しで正しいバッファ長が取得され、2 番目の呼び出しでレコードがガベージで埋められます。
これは Delphi 2007 では問題なく動作しますが、IpTypes.pas で AnsiString を使用して明示的に宣言されていても、pAdapterinfo 戻りレコードに Unicode ガベージが含まれているため、XE6 では失敗します。
システムは Win7(64) ですが、32 ビット用にコンパイルしています。
uses iphlpapi, IpTypes;
function GetFirstAdapterMacAddress:AnsiString;
var pAdapterInfo:PIP_ADAPTER_INFO;
BufLen,Status:cardinal; i:Integer;
begin
result:='';
BufLen:= sizeof(IP_ADAPTER_INFO);
GetAdaptersInfo(nil, BufLen);
pAdapterInfo:= AllocMem(BufLen);
try
Status:= GetAdaptersInfo(pAdapterInfo,BufLen);
if (Status <> ERROR_SUCCESS) then
begin
case Status of
ERROR_NOT_SUPPORTED: raise exception.create('GetAdaptersInfo is not supported by the operating ' +
'system running on the local computer.');
ERROR_NO_DATA: raise exception.create('No network adapter on the local computer.');
else
raiselastOSerror;
end;
Exit;
end;
while (pAdapterInfo^.AddressLength=0) and (pAdapterInfo^.next<>nil) do
pAdapterInfo:=pAdapterInfo.next;
if pAdapterInfo^.AddressLength>0 then
for i := 0 to pAdapterInfo^.AddressLength - 1 do
result := result + IntToHex(pAdapterInfo^.Address[I], 2);
finally
Freemem(pAdapterInfo);
end;
end;
アップデート:
さらにチェックを行いました。1 つのフォームと 1 つのボタンを備えた新しい単純なアプリケーションを作成し、ボタンが押されて機能したときにルーチンを呼び出しました。
違いは...作業形式では、IP_ADAPTER_INFO のサイズは 640 バイトです。
このルーチンをより複雑なアプリケーションで使用すると失敗し、IP_ADAPTER_INFO のサイズが 1192 バイトと表示されます。
この時点で、構造体の ansi char の型を unicode char に変更することをコンパイラが一方的に決定しているようです。デバッガーは、AdapterName および説明フィールドを Unicode 形式で表示しています。システム ソース コードの grep を実行しました。このデータ型の他のバージョンは、Indy ライブラリ以外のライブラリ コードで宣言されておらず、単なる重複です。
IPtypes のデータ構造定義は次のとおりです。
PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
{$EXTERNALSYM PIP_ADAPTER_INFO}
_IP_ADAPTER_INFO = record
Next: PIP_ADAPTER_INFO;
ComboIndex: DWORD;
AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of AnsiChar;
Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of AnsiChar;
AddressLength: UINT;
Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
Index: DWORD;
Type_: UINT;
DhcpEnabled: UINT;
CurrentIpAddress: PIP_ADDR_STRING;
IpAddressList: IP_ADDR_STRING;
GatewayList: IP_ADDR_STRING;
DhcpServer: IP_ADDR_STRING;
HaveWins: BOOL;
PrimaryWinsServer: IP_ADDR_STRING;
SecondaryWinsServer: IP_ADDR_STRING;
LeaseObtained: time_t;
LeaseExpires: time_t;
end;
コンパイラのバグのようです。