Я пытаюсь перенести некоторый код, который работает в Delphi XE8, в Delphi 10 Seattle. Этот код вызывает функцию GetPath в Winapi.Windows.
Новая сигнатура функции Win32 API:
function GetPath(DC: HDC; Points: PPointL; Types: PByte; nSize: Integer): Integer; stdcall;
В XE8 ранее у функции был параметр "var Points,Types", известный как параметр "var untyped".
Исправление кода для работы с Delphi 10 Seattle означает «унификацию» произвольных типов в коде приложения для использования именно тех типов, которые объявлены в самом модуле. Однако меня смущает то, что существует два типа, PPointL и TPoint, и когда я запускаю функцию GetPath, заполняемые ею данные заполняются в массив записей _POINTL, объявленный таким образом в Winapi.Windows:
type
_POINTL = record { ptl }
x: Longint;
y: Longint;
end;
{$EXTERNALSYM _POINTL}
PPointL = ^TPointL;
TPointL = _POINTL;
Однако есть и другой тип TPoint, объявленный в System.Types:
TPoint = record
X: FixedInt;
Y: FixedInt;
public
В другом месте FixedInt имеет псевдоним Longint как для 32-битной, так и для 64-битной Windows, поэтому, насколько я могу судить, TPoint и _POINTL эквивалентны, по крайней мере, на платформе Windows.
Если весь существующий код компонентов приложения использует тип с именем TPoint, например:
procedure AddPoint(const P:TPoint);
... Какой мне смысл понимать ситуацию внутри исходников RTL в Delphi 10? Каким должен быть мой подход к исправлению этого? Псевдоним TPoint для _POINTL на уровне устройства?
Как это исправить и продолжить? Поскольку этот код является коммерческим компонентом, я думаю, что подожду, пока поставщик исправит это, но тогда я думаю, что понимание _POINTL и TPoint в RTL и почему эти структуры избыточно/дублируются в определении, поможет другие переносят низкоуровневый код Win32 с Delphi XE8 на Delphi 10 Seattle.
Обновление: в качестве обходного пути я обнаружил, что могу повторно объявить импорт функции GetPath и оставить ее как нетипизированную переменную в моем собственном импорте области реализации частного модуля и продолжить:
{$ifdef D23}
{$POINTERMATH ON}
// Delphi 10 Seattle: function GetPath(DC: HDC; Points: PPointL; Types: PByte; nSize: Integer): Integer; stdcall;
// previously had "var Points,Types" untyped,
const
gdi32 = 'gdi32.dll';
{$EXTERNALSYM GetPath}
function GetPath(DC: HDC; var Points, Types; nSize: Integer): Integer; stdcall; external gdi32 name 'GetPath';
{$endif}
PPoint
, а неPPointL
. - person Rudy Velthuis   schedule 01.09.2015POINTL
вместоPOINT
по причинам, которые я не могу понять. Но да,GetPath
используетPOINT
. - person David Heffernan   schedule 01.09.2015POINTL
не является избыточным в Delphi. FWIW,POINTL
иRECTL
, похоже, используются в API-интерфейсах метафайлов. Я понятия не имею, почему они не могут использовать обычные структурыPOINT
иRECT
. Вероятно, это конкурирующая группа разработчиков внутри MS, не общающаяся с остальными. <г> - person Rudy Velthuis   schedule 02.09.2015