• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 5017
  • Last Modified:

Integer value Pointer

Ok this is interesting Question.

If you have noticed every component have property "TAG" and its integer. Not many components have property pointer. For exsample every TTreeNode has propery "Data" wich is poiner its value is nil and i can use this pointer for my extensions, like adding some class or so.

So what is my idea.

pointer value is integer only in hex decimal. So for better view i will show my idea

I creare TList.

T:=TList.create;

I asign T pointer value to a pointer P

P:=T

For my component i have "TAG" propery I want to add pointer valu to "TAG" converting pointer in integer value

it should look like so

p:=$953F10;

i:=pointertoint(p);//i know pointertoint function doesn't exist :) but that is the idea i wan't to get pointer value to integer and beck from integer value to pointer :).

commponet.tag=i;

So why i'm so interested is this kind of taging :) if component doesn't have pointer poperty i can use "tag" property like pointer to some object.

But i need these to function:

pointertoint(p:pointer):integer;
inttopointer(i:integer):pointer;

I think this idea is nice i will continue to solve this interesting idea my self but fieel free to try to solve it first.
0
Kristao
Asked:
Kristao
  • 2
  • 2
  • 2
  • +3
1 Solution
 
Russell LibbySoftware Engineer, Advisory Commented:
Because pointer and integer are both 4 byte data types, a simple cast can be used.

var i: Integer;
     p: Pointer;
begin


 i:=Integer(p); // Cast pointer to int
 p:=Pointer(i); // Cast int to pointer

end;

--

Regards,
Russell





0
 
David_WardCommented:
Yep, Russel is spot on ...

-----------------------------

TComponent.Tag

Stores an integer value as part of a component.

property Tag: Longint;

Description

Tag has no predefined meaning. The Tag property is provided for the convenience of developers. It can be used for storing an additional integer value or it can be typecast to any 32-bit value such as a component reference or a pointer.



0
 
huferryCommented:
You can freely type cast any 32-bit variable (or less) to another 32-bit type.
32 bit type in Delphi are: pointer, integer, cardinal, single.

So if you want to 'save' a pointer value to the 'tag' property you can do that:

Button1.Tag := Integer(Button2);

which.. later on, you can do this:

TButton(Button1.Tag).Click;

Or.... the other way around, you can create a list of integer values using TList:

var I: Integer;
MyList.Add(TObject(I)); // type cast integer to pointer type

... and retrieve it again:

I := Integer(MyList.Items[0]);

Note that the compiler will give you warning of unsafe typecasting, you'll need
to be very carefull with this method.

regards,
Ferry
0
[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

 
huferryCommented:
Or... of course you can create your 2 conversions functions:

function PointerToInt(APointer: Pointer): Integer;
begin
  Result := Integer(APointer);
end;

function IntToPointer(AInt: Integer): Pointer;
begin
  Result := Pointer(AInt);
end;

0
 
TheRealLokiSenior DeveloperCommented:
here's a working example from 1 of my projects

type TPositionObject = class
public
    startx, starty: integer;
end;


panel2.Tag := Integer(TPositionObject.Create);


procedure TForm1.Panel_MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
        TPositionObject( (Sender AS TPanel).Tag).startx := X;
        TPositionObject( (Sender AS TPanel).Tag).starty := Y;
        TPositionObject( (Sender AS TPanel).Tag).Moving := True;
    end;

0
 
kfoster11CEOCommented:
Keep in mind that Pointer and Longint while in 32 bit windows are the same size.  That is not guaranteed in 64 bit windows.  Not sure how Delphi and Borland will/ or do handle this in 64 bit.
0
 
David_WardCommented:
Also keep in mind that -some- exisiting 3rd party component sets use this for there own purposes, commonly, internationalisation and skinning components, for instance.
0
 
ruanlab123Commented:
I created this little experiment to see what will happen.  I learned something today.

procedure TForm1.Button1Click(Sender: TObject);
var
  _pointers : TList;
  x, iTestP, iTestV ,i: integer;
  lb, lsTest : TListBox;
begin
  x := 5;
  lb := ListBox1; // A listbox on my form
  lb.Items.Add('Line 1');
  lb.Items.Add('Line 2');

  _pointers := TList.Create;
  //You need to add the @ before type variables to get a pointer to that value.
  _pointers.Add(@x);
  _pointers.Add(lb);//Objects are always pointer.

  lsTest := TListBox(_pointers.Items[1]);//Retreive listbox pointer from IList
  iTestP := integer(_pointers.Items[0]);//This returns a pointer to integer value
  iTestV := integer(_pointers.Items[0]^);//Returns the value of the integer

  //iTestP is a pointer to my origional value.  You can also retreive that
  //value by
  iTestV := integer(pointer(iTestP)^);

  //This means you can store the pointer (iTestP) in the tag element, and
  //later on retreive the value like just above.

  ShowMessage('Pointer to origional value ' + IntToStr(iTestP));
  ShowMessage('Origional value ' + IntToStr(iTestV));

  for i := 0 to lsTest.Items.Count-1 do begin
    ShowMessage(lsTest.Items[i]);
  end;
end;
0
 
kfoster11CEOCommented:
ruanlab123 just for clarification in case someone reading your post doesn't understand it.
------------------

you declared your x,iTestP,iTestv as Integers in the local context and got the address to those pointers with the @ operator.  These pointers are not valid outside this proc's scope.

try this with your test.

x :PInteger;  or X: ^Integer;  (same thing).

now x is a true pointer type.

New(X) will get the memory for an Integer and X will POINT to that memory (or in English the value of X is the @ of the memory returned from the New function).

While the pointer X is local to the scope of your function.  The memory that X POINTS to is not.  So if you add x to a TList that is global to an object then it can be accessed by any code that has access to the object.  ex.  Tlist.Get accesses a list of pointers that are global to the TList object.

When you wish to access the value that X points to you use the^.

ex.
 var
    MyInt : Integer
begin
   MyInt := X^;  not X;
end;

also You obtained the memory with the NEW function.  It is your responsibility to release it with the DISPOSE function.
Dispose(X);

------------
Cheers;



0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now