Using Delphi Self Finder

I need to get a pointer to an instance of a class inside this instance. I can’t use “I” directly, I need a storage pointer for future use. I tried the following code:

type
    TTest = class(TObject)
    public
        class function getClassPointer: Pointer;
        function getSelfPointer: Pointer;
    end;

class function TTest.getClassPointer: Pointer;
begin
    Result := Pointer(Self);
end;

function TTest.getSelfPointer: Pointer;
begin
    Result := Pointer(Self);
end;

And both results are wrong - this code:

test := TTest.Create;
Writeln('Actual object address: ', IntToHex(Integer(@test), 8));
Writeln('Class "Self" value: ', IntToHex(Integer(test.getClassPointer()), 8));
Writeln('Object "Self" value: ', IntToHex(Integer(test.getSelfPointer()), 8));

returns:

Actual object address:    00416E6C
Class "Self" value:       0040E55C
Object "Self" value:      01EE0D10

Please help me understand what is the meaning of "I"? Is the "I" a pointer to this instance of the class? How to use this pointer for future use outside this object? How to get the correct pointer from this value?

+5
source share
2 answers

You are trying to compare three completely different objects.

@test , , .

test.getClassPointer() , , , , . . - , , .

test.getSelfPointer() . ( ) . test.getSelfPointer() : ()

(, ):

type TTest = class
     end;

var test1: TTest;
    test2: TTest;

begin
  test1 = TTest.Create;  // allocates memory from the global heap, stores pointer
  test2 = test1;         // copies the pointer to the object into test2 variable
  writeln("Test1 variable points to: ", IntToHex(Integer(Pointer(test1))));
  writeln("Test2 variable points to: ", IntToHex(Integer(Pointer(test1))));
end.
+12

test ,

Writeln('Actual object address: ', IntToHex(Integer(Pointer(test)), 8));

, , getSelfPointer. , test, :

var
  SecondReferenceToTest: TTest;
SecondReferenceToTest := test;

, - :

type
  TTest = class(TObject)
  public
    Name: string;
  end;

procedure TestProc;
var
  test, SecondReferenceToTest: TTest;
begin
  test := TTest.Create;
  try
    test.Name := 'Named via "test" reference';
    SecondReferenceToTest := test;
    ShowMessage(SecondReferenceToTest.Name);
  finally
    test.Free;
  end;
end;
0

All Articles