Старый проект не может быть скомпилирован в Delphi 4 из-за проблем с указателями - PullRequest
1 голос
/ 04 февраля 2020

У меня совсем нет опыта в Delphi, и у меня есть очень старый проект, который можно скомпилировать в Delphi 2-й, 3-й версий, но не работает в Delphi 4. Проблема в указателях которые работают по-другому в новой версии.

Эти фрагменты кода вызывают ошибку " Требуется переменная ":

pEnabled := @pClrWire_s^.enabled;
pEnabled        := @Enabled;
pNEnabled    := @pName_s^.Enabled;

, где pEnabled это :

const
pEnabled : ^boolean   = nil;

и pClrWire_s и pName_s также являются указателями:

pClrWire_s : TpImage;      {pointer to an image of colored wire}
pName_s    : TpNamed;      {pointer to the identifier}

Описание TpImage и TpNamed можно найти в других файлах проекта:

type
  TpImage   = ^TImage;
TpNamed = ^TNamed;
TNamed = class(TLabel)

Можно ли решить эту проблему без серьезного переписывания всего кода? и что вызывает такую ​​проблему с Delphi 4?

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Следующая минимальная программа отлично работает в Delphi4:

program ProjTestWriteableConstants; 
{$APPTYPE CONSOLE} 
{$J+} 
type 
  TMyPt = ^Boolean; 
const 
  pBool : TMyPt = nil; 
var 
  Enabled : Boolean; 
begin 
   pBool := @Enabled; 
end.

Из документации Delphi 4:

Type       Switch

Syntax     {$J+} or {$J-}{$WRITEABLECONST ON} or {$WRITEABLECONST OFF}

Default    {$J+}{$WRITEABLECONST ON}

Scope      Local

Директива $ J определяет, могут ли типизированные константы быть модифицировано или нет. В состоянии {$ J +} типизированные константы могут быть изменены и, по сути, являются инициализированными переменными. В состоянии {$ J-} ​​типизированные константы действительно постоянны, и любая попытка изменить типизированную константу заставляет компилятор сообщать об ошибке.

В предыдущих версиях Delphi и Borland Pascal, типизированные константы всегда были доступны для записи, что соответствует состоянию {$ J +}. Старый исходный код, в котором используются записываемые типизированные константы, должен быть скомпилирован в состоянии {$ J +}, но для новых приложений рекомендуется использовать инициализированные переменные и скомпилировать код в состоянии {$ J-}.


Примечание:

  • Изменение по сравнению с предыдущими версиями: В предыдущих версиях Delphi и Borland Pascal, типизированные константы всегда были доступны для записи, что соответствует состоянию {$ J +}. Старый исходный код, использующий записываемые типизированные константы, должен быть скомпилирован в состоянии {$ J +} ...
  • Область действия директивы компилятора {$ J +} является локальной, что означает, что каждый модуль, который объявляет записываемую константу, должен включать переключатель {$ J +}.

Вывод: чтобы это работало, вы должны поместить директиву компилятора {$ J +} в каждый модуль, где записываемый константа объявлена.

0 голосов
/ 06 февраля 2020

Вот полное решение, протестированное с последней Delphi (D10.3, которая действительно Delphi версия 26, если сравнивать с ранним Delphi номером версии, но это другая история):

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;

type
  TpImage = ^TImage;

{$J+}   // enable writable constant
const
  pEnabled : ^boolean   = nil;

var
  pClrWire_s : TpImage;

type
  TForm1 = class(TForm)
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

end.

Как сказали в своем комментарии Далия Прасникар и Джерри Колл, ключом является включение присваиваемой типизированной константы. Вы можете сделать это либо с помощью {$ J +} в исходном коде, либо с помощью параметров проекта, расположенных в разделе Параметры проекта / Сборка / Delphi Компилятор / Компиляция / Параметры синтаксиса / Назначаемая типизированная константа.

Дайте мне знать, если это работает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...