Solved

Typecasting a pointer to a record

Posted on 1998-09-02
15
442 Views
Last Modified: 2010-04-04
A routine is expecting a type PBYTE which is defined:
   PBYTE = ^Byte;
   procedure MyProc (buffer : PBYTE);

I need to pass it a pointer to a packed record:
  PHeader = ^THeader;
  THeader = packed record
  end;

e.g.
   pMyHeader : PHeader;
   MyProc(pMyHeader);

I'ev tried many options for typecasting, and the only one the compiler agrees with is:
   MyProc( @(pMyHeader^) );

This doesn't seem right.
Any one has a better suggestion?
0
Comment
Question by:vang
  • 7
  • 3
  • 2
  • +3
15 Comments
 

Author Comment

by:vang
ID: 1338451
Edited text of question
0
 

Expert Comment

by:chrismo
ID: 1338452
This seems a bit cleaner:

MyProc(PByte(pMyHeader));
0
 

Author Comment

by:vang
ID: 1338453
Thank you for your quick response.
However, I must reject your propsed answer.
I've tried it before, and I get an "Incompatible types" error message.
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

Expert Comment

by:chrismo
ID: 1338454
Is this at run-time, or compile? Mine compiled okay ... maybe I didn't set it up correctly.
0
 

Author Comment

by:vang
ID: 1338455
It is at compile time.
0
 

Expert Comment

by:chrismo
ID: 1338456
Do you have some source you could send? If so, send it to chrismo@workmail.com and I'll see if it compiles for me...
0
 
LVL 4

Expert Comment

by:BoRiS
ID: 1338457
vang

I was having the same problema at one stage and I found this on the net helped me out, maybe it will help you too...

unit Unit1;

                              interface

                              uses
                                SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
                                Forms, Dialogs, StdCtrls;

                              type
                                TForm1 = class(TForm)
                                  Button1: TButton;
                                  Button2: TButton;
                                  procedure Button1Click(Sender: TObject);
                                  procedure FormCreate(Sender: TObject);
                                  procedure FormDestroy(Sender: TObject);
                                  procedure Button2Click(Sender: TObject);
                                private
                                  List : TList;
                                end;

                              var
                                Form1: TForm1;

                              implementation

                              {$R *.DFM}

                              type
                                TPersonRec = record
                                  Name: string;
                                  Age: Byte;
                                end;
                                PPersonRec = ^TPersonRec;

                              procedure TForm1.Button1Click(Sender: TObject);
                              var
                                PersonRec : PPersonRec;
                              begin
                                New(PersonRec);
                                try
                                  PersonRec^.Name := 'Rick Rogers';
                                  PersonRec^.Age := 29;
                                  List.Add(PersonRec);
                                except
                                  Dispose(PersonRec);
                                  raise;
                                end;
                              end;

                              procedure TForm1.FormCreate(Sender: TObject);
                              begin
                                List := TList.Create;
                              end;

                              procedure TForm1.FormDestroy(Sender: TObject);
                              var
                                I : Integer;
                              begin
                                for I := 0 to (List.Count - 1) do Dispose(PPersonRec(List[I]));
                                List.Free;
                              end;

                              procedure TForm1.Button2Click(Sender: TObject);
                              var
                                PersonRec : PPersonRec;
                              begin
                                PersonRec := PPersonRec(List[0]);
                                ShowMessage(PersonRec^.Name);
                              end;

                              end.

Its from a post on the forums from Rick Rogers

Later
BoRiS
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1338458
You need to change.....this is actually just a guess....you can not typecast a PByte as a THeader...maybe packed record of PByte  or something similar.....

PBYTE = ^Byte;
      procedure MyProc (buffer : PBYTE); //Change this to procedure MyProc(Buffer : THeader^);
     PHeader = ^THeader;
     THeader = packed record
     end;
      pMyHeader : PHeader;
      MyProc(pMyHeader);

   I'ev tried many options for typecasting, and the only one the compiler agrees with
   is:
      MyProc( pMyHeader ); //or MyProc(@pMuHeader);..not exactly sure which one should be

0
 

Author Comment

by:vang
ID: 1338459
I'm sending...
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1338460
Try "MyProc(pointer(pMyHeader));"

Regards, Madshi.
0
 

Author Comment

by:vang
ID: 1338461
Maby I didn't understand your answer.
Can you please pin point me?
0
 

Author Comment

by:vang
ID: 1338462
Victornet,
"MyProc" is not actualy mine.
I can't change its expected type.
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1338463
vang,

>> Maby I didn't understand your answer.
>> Can you please pin point me?

Who are you to talking to? To me? Have you tested my suggestion?

Regards, Madshi.
0
 
LVL 3

Accepted Solution

by:
rickpet earned 100 total points
ID: 1338464
The easiest way is to pass pointers...you can use a pointer to point to any pointer type here's an example...No casting needed.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
 PBYTE = ^Byte;
 PHeader = ^THeader;
 THeader = packed record
   MyValue: integer;
 end;


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Header: THeader;

implementation

{$R *.DFM}

procedure CallProc(pRecord: pByte);
var
  tmpPointer: pointer;
  tmpHeader: PHeader;
begin
  tmpPointer := pRecord;
  tmpHeader := tmpPointer;
  ShowMessage(IntToStr(tmpHeader^.MyValue));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Header.MyValue := 99;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  tmpPointer: pointer;
  tmpHeader: PHeader;
begin
   tmpPointer := @Header;
   CallProc(tmpPointer);
end;

end.

0
 

Author Comment

by:vang
ID: 1338465
This answer is agreeable, though the code still looks a bit messy, at least to me.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question