В процессе разработки приложений на Delphi и Object Pascal разработчики часто сталкиваются с ошибкой ACCESS VIOLATION, особенно при работе с классами, объявленными в других модулях. В этой статье мы разберем конкретный случай такой ошибки, рассмотрим ее причины и предложим решения.
Описание проблемы
Пользователь столкнулся с ошибкой External ACCESS VIOLATION при попытке доступа к компоненту формы (lblHdr), объявленной в модуле sbClrMsg, из другого модуля WordPlaySuperMsgVersion2. Ошибка возникает на строке:
frmsbClrDlg.lblHdr.Caption := 'Confirm program exit . . .';
При этом проект успешно компилируется, но падает во время выполнения.
Анализ кода
Основные модули участвующие в проблеме:
Модуль sbClrMsg - содержит объявление формы TfrmsbClrDlg:
Основная причина ошибки ACCESS VIOLATION в данном случае - попытка доступа к экземпляру формы, который не был создан. Это происходит потому, что:
Форма frmsbClrDlg объявлена как глобальная переменная в модуле sbClrMsg
Но она не создается автоматически при запуске приложения
В файле проекта (WPSMV2.lpr) отсутствует строка создания этой формы
Решения проблемы
1. Добавление создания формы в файле проекта
Самый простой и правильный способ - добавить создание формы в файл проекта:
program WPSMV2;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
{$IFDEF HASAMIGA}
athreads,
{$ENDIF}
Interfaces,
Forms,
sbClrMsg, // Добавляем модуль с формой
WordPlaySuperMsgVersion2;
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TfrmsbClrDlg, frmsbClrDlg); // Создаем вторую форму
Application.Run;
end.
2. Использование автосоздания форм через IDE
В Lazarus:
1. Откройте Project → Project Options → Forms
2. Перенесите TfrmsbClrDlg из "Available forms" в "Auto-create forms"
3. IDE автоматически добавит нужный код в файл проекта
3. Создание формы вручную при необходимости
Альтернативный подход - создавать форму динамически, когда она нужна:
procedure TForm1.btnQuitClick(Sender: TObject);
var
Dlg: TfrmsbClrDlg;
begin
Dlg := TfrmsbClrDlg.Create(nil);
try
Dlg.lblHdr.Caption := 'Confirm program exit . . .';
Dlg.lblText.Caption := 'Are you sure you want to' + sLineBreak + 'end the program?';
// ... остальные настройки формы
if Dlg.ShowModal = mrYes then
Close;
finally
Dlg.Free;
end;
end;
Рекомендации по архитектуре
Избегайте глобальных переменных форм - лучше создавайте формы, когда они нужны, и освобождайте после использования
Минимизируйте зависимости между модулями - используйте интерфейсы или события для взаимодействия между формами
Проверяйте существование объектов перед доступом к их свойствам и методам
Заключение
Ошибка ACCESS VIOLATION при доступе к классу из другого модуля обычно возникает из-за того, что экземпляр класса не был создан. В рассмотренном случае решение заключалось в добавлении модуля с формой в uses файла проекта и создании экземпляра формы при запуске приложения.
Правильное управление жизненным циклом объектов - ключ к стабильной работе приложения. Используйте предложенные решения в зависимости от ваших требований к архитектуре приложения.
Ошибка ACCESS VIOLATION возникает при попытке доступа к неинициализированному экземпляру класса формы из другого модуля в Delphi/Pascal.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.