我正在尋找方法來獲取Delphi記錄中字段的偏移量。以下兩種方法可行,但我希望有一個更清晰的方法。基本上我會喜歡第三個showmessage工作。有任何想法嗎?Delphi:記錄字段的偏移量
編輯: 好的,下面的答案正常工作,謝謝!作爲參考,這裏的彙編輸出的各種選項:
---- result:=longint(@abc.c)-longint(abc); ----
lea edx,[eax+$08]
sub edx,eax
mov eax,edx
---- mov eax,offset rec_a.c ----
mov eax,$00000008
---- result:=longint(@rec_a(nil^).c); ----
xor eax,eax
add eax,$08
EDIT2:看起來這是前一個問題的重複:previous similar question由RRUZ如下所述。如上所示,另一種方法是聲明一個全局變量並按如下所示使用它。奇怪的是,編譯器仍然不能在彙編輸出中看到正確的值,所以爲了提高效率和可讀性,最好使用nil方法。
---- var ----
---- rec_a_ofs:rec_a; ----
---- ... ----
---- result:=longint(@rec_a_ofs.c)-longint(@rec_a_ofs); ----
mov eax,$0045f5d8
sub eax,$0045f5d0
edit3:好吧,修改後的代碼與所有已知的方法來完成此操作。請注意,爲3rd,4th和5th(類方法)生成的彙編代碼是相同的,無論它們是否內聯。當你做這些事情時,選擇你最喜歡的方式!
type
prec_a=^rec_a;
rec_a=record
a:longint;
b:byte;
c:pointer;
class function offset_c:longint;static;inline;
end;
//const
// rec_a_field_c_offset=longint(@rec_a(nil^).c); // no known way to make this work
{$warnings off}
function get_ofs1:longint;inline;
var
abc:^rec_a;
begin
result:=longint(@abc.c)-longint(abc);
end;
{$warnings on}
function get_ofs2:longint;
asm
mov eax,offset rec_a.c
end;
function get_ofs3:longint;inline;
begin
result:=longint(@rec_a(nil^).c);
end;
function get_ofs4:longint;inline;
begin
result:=longint(@prec_a(nil).c);
end;
class function rec_a.offset_c:longint;
begin
result:=longint(@prec_a(nil).c);
end;
var
rec_a_ofs:rec_a;
function get_ofs6:longint;inline;
begin
result:=longint(@rec_a_ofs.c)-longint(@rec_a_ofs);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(inttostr(get_ofs1));
showmessage(inttostr(get_ofs2));
showmessage(inttostr(get_ofs3));
showmessage(inttostr(get_ofs4));
showmessage(inttostr(rec_a.offset_c));
showmessage(inttostr(get_ofs6));
// showmessage(inttostr(rec_a_field_c_offset));
end;
BASM代碼中不需要'offset'關鍵字;只是'mov eax,rec_a.c'。 – kludg
[獲取結構變量的位置](http:// stackoverflow。com/questions/13168959/get-position-of-a-struct-var) – RRUZ
@serg甚至冗餘代碼可能會增加soem安全性 - 消除你沒有預料到的歧義性或者在錯誤輸入和更寬鬆的編碼時造成語法錯誤將編譯錯誤的結果 –