Reputation: 95
when i migrate from Delphi 6 to Delphi 10.2 Tokyo i get error when i try to casting pointer of ^PChar to array of PChar
type
PServEnt = ^TServEnt;
TServEnt = packed record
s_name: PChar; // official service name
s_aliases: ^PChar; // alias list
s_port: Smallint; // protocol to use
s_proto: PChar; // port #
end;
function TIdStackWindows.WSGetServByPort(
const APortNumber: Integer): TIdStrings;
var
ps: PServEnt;
i: integer;
p: array of PChar;
begin
Result := TIdStringList.Create;
p := nil;
try
ps := GetServByPort(HToNs(APortNumber), nil);
if ps <> nil then
begin
Result.Add(ps^.s_name);
i := 0;
p := Pointer(ps^.s_aliases); // get error Incompatible types: 'Dynamic array' and 'Pointer'
while p[i] <> nil do
begin
Result.Add(PChar(p[i]));
inc(i);
end;
end;
except
Result.Free;
end;
end;
this code working well at Delphi 2010 ,how to make it correct at Delphi 10.2 Tokyo
Upvotes: 1
Views: 955
Reputation: 612804
The error message is correct, and if the code compiled in earlier versions of Delphi then that was because those earlier versions of the compiler were deficient.
A dynamic array is more than just a pointer to the first element. It also encapsulates the meta data which stores the length of the array, and the reference count. Your cast is therefore not valid. You got away with this invalid code because you did not attempt to access this meta data, but that's as much by chance as through intention.
Don't attempt to cast to a dynamic array. Instead use pointer arithmetic. For instance:
function TIdStackWindows.WSGetServByPort(
const APortNumber: Integer): TIdStrings;
var
ps: PServEnt;
p: PPChar;
begin
Result := TIdStringList.Create;
try
ps := GetServByPort(HToNs(APortNumber), nil);
if ps <> nil then
begin
Result.Add(ps^.s_name);
p := PPChar(ps^.s_aliases); // cast needed due to Indy record type's use of un-nameable type
while p^ <> nil do
begin
Result.Add(p^);
inc(p);
end;
end;
except
Result.Free;
raise;
end;
end;
I changed the type declaration of the alias list to PPChar
to avoid incompatible type errors when assigning to the local variable of that type.
Note also that I have corrected your exception handling which was previously swallowing exceptions and returning an invalid object reference.
Upvotes: 4