4

我想获得结构/记录的“位置”。

假设我有这个记录:

type
  MyStruct = record
    MyInteger   : Integer;
    MyInteger2  : Integer;
    MyInteger3  : Integer;
    MyFunc      : function (FirstParam : WideString; SecondParam : String) : Integer;
    MyString    : String;
    MyString2   : WideString;
    MyPchar     : pchar;
end;

如您所见,该记录的大小为 28 字节(7 vars x 4 字节)。基本上是因为所有变量都是 4 字节变量(例如整数)或指针(也是 4 字节)。现在假设我们将这个结构加载到内存地址 (X = 0) 中(这也意味着 MyInteger 的地址将为 0)。MyInteger3 的地址(例如)将是 8 (注意 X = 0 !)如何动态获取结构的位置(数字/地址)?

希望大家明白我的意思吗?提前致谢。

顺便说一句:结构中的任何 Var 是否总是 4 个字节?编辑:如果您修复 spcae ,这是错误的:String[100]

4

2 回答 2

9

您可以使用一些指针算法获得任何记录成员的偏移量:

type
  PMyStruct = ^MyStruct;

var
  Offset: Integer;
begin
  Offset := Integer(@(PMyStruct(nil).MyInteger3));
  // or:
  // Offset := Integer(Addr(PMyStruct(nil).MyInteger3));
end;

如果你想要函数的偏移量,你需要这样编码:

Offset := Integer(@@PMyStruct(nil).MyFunc);
// or:
// Offset := Integer(Addr(@PMyStruct(nil).MyFunc));
于 2012-11-01T02:39:05.167 回答
7
program OffsetTest; {$APPTYPE CONSOLE}

type
  f = function (FirstParam : WideString; SecondParam : String) : Integer;
  TStruct = record
    MyInteger   : Integer;
    MyInteger2  : Integer;
    MyInteger3  : Integer;
    MyFunc      : ^f;
    MyString    : String;
    MyString2   : WideString;
    MyPchar     : pchar;
  end;

var MyStruct :TStruct;

begin
  Writeln( int64(@(MyStruct.MyInteger )) - int64(@(MyStruct)));
  Writeln( int64(@(MyStruct.MyInteger2)) - int64(@(MyStruct)));
  Writeln( int64(@(MyStruct.MyInteger3)) - int64(@(MyStruct)));
  Writeln( int64(@(MyStruct.MyFunc    )) - int64(@(MyStruct)));
  Writeln( int64(@(MyStruct.MyString2 )) - int64(@(MyStruct)));
  Writeln( int64(@(MyStruct.MyPchar   )) - int64(@(MyStruct)));
  Readln;
end.

32 位版本的结果:

0 
4 
8
12
20
24

64 位版本的结果:

0
4
8
16
32
40

64位结果,打包记录:

0
4
8
12
28
36

显示不同的结果以指出在代码中依赖这些偏移量可能是个坏主意。或者至少要非常清楚不同的情况可能会导致不同的偏移量。

于 2012-11-01T02:47:00.100 回答