Главная страница | назад





Article #16668: Typecasting

 Question and Answer Database

FAQ1668D.txt   Typecasting
Category   :Object Pascal
Platform    :All
Product    :All 32 bit  

Question:
Many Windows functions claim to want PChar parameters in the
documentation, but they are defined as requiring LongInts. Is 
this a bug?

Answer:
No, this is where "typecasting" is used. Typecasting allows you 
to fool the compiler into thinking that one type of variable is 
of another type for the ultimate in flexibility. The last 
parameter of the Windows API function SendMessage() is a good 
example. It is documented as requiring a long integer, but 
commonly requires a PChar for certain messages 
(i.e. WM_WININICHANGE).  Generally, the variable you are
typecasting from must be the same size as the variable type you 
are casting it to. In the SendMessage example, you could 
typecast a PChar as a longint, since both occupy 4 bytes 
of memory:

Example:

var
   s : array[0..64] of char;
begin
  StrCopy(S, 'windows');
  SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@S));
end;

Pointers are the easiest to typecast, and are the most flexible 
since you can pass anything to the called procedure.  They are
also the most dangerous for the same reason. You can also use 
untyped variable parameters for convenience, although var 
parameters are really pointers behind the scenes.

Example:

type
  PBigArray = ^TBigArray;
  TBigArray = Array[0..65000] of char;

procedure ZeroOutPointerVariable(P : pointer; size : integer);
var
  i : integer;

begin
  for i := 0 to size - 1 do
    PBigArray(p)^[i] := #0;
end;

procedure ZeroOutUntypedVariable(var v, size : integer);
var
  i : integer;

begin
  for i := 0 to size - 1 do
    TBigArray(v)[i] := #0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s : string[255];
  i : integer;
  l : longint;

begin
  s := 'Hello';
  i := 10;
  l := 2000;

  ZeroOutPointerVariable(@s, sizeof(s));
  ZeroOutPointerVariable(@i, sizeof(i));
  ZeroOutPointerVariable(@l, sizeof(l));

  s := 'Hello';
  i := 10;
  l := 2000;

  ZeroOutUntypedVariable(s, sizeof(s));
  ZeroOutUntypedVariable(i, sizeof(i));
  ZeroOutUntypedVariable(l, sizeof(l));
end;

7/16/98 4:31:28 PM
 

Last Modified: 01-SEP-99