我有代碼,在 WIN32 下多年運行良好。但是昨天,在 WIN64 下編譯后,嘗試獲取 wki100_langroup 欄位時出現奇怪的 ACCESS_VIOLATION 錯誤。這段代碼哪里錯了?(計算機不在域中,在 Delphi 11 除錯視窗中我可以看到,該欄位為空)
const
NERR_SUCCESS = 0;
type
WKSTA_INFO_100 = record
wki100_platform_id: DWORD;
wki100_computername: LPWSTR;
wki100_langroup: LPWSTR;
wki100_ver_major: DWORD;
wki100_ver_minor: DWORD;
end;
LPWKSTA_INFO_100 = ^WKSTA_INFO_100;
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; var BufPtr: Pointer): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: Pointer;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
更新: 將指標更改為 PByte 后,我有同樣的例外
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; BufPtr: PByte): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: PByte;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, @PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
Win32的截圖:

和 Win64 斷點:

uj5u.com熱心網友回復:
這些癥狀表明其他一些代碼更改了WKSTA_INFO_100記錄型別的默認記錄對齊方式。
在 32 位編譯器下不會產生影響,因為記錄中的所有值也是 32 位的,因此即使指定了其他對齊大小,它們也會正確對齊。
64位下編譯器DWORD是32位的,而LPWSTR是64位的。使用默認的 8 位元組對齊方式,這意味著 . 之后將插入 4 個填充位元組wki100_platform_id。如果使用其他對齊方式,則以下欄位將不在正確位置。
要更正此問題,您需要{$A8}在型別宣告之前指定 8 位元組對齊。
type
{$A8}
WKSTA_INFO_100 = record
wki100_platform_id: DWORD;
wki100_computername: LPWSTR;
wki100_langroup: LPWSTR;
wki100_ver_major: DWORD;
wki100_ver_minor: DWORD;
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/460933.html
標籤:德尔福 温纳皮 delphi-11-亚历山大
