Delphi TDataSet в пакете времени выполнения

Я создаю пакет времени выполнения, который содержит классы, которые может использовать мое основное приложение, но у меня проблемы с доступом к данным. Мое основное приложение содержит базу данных TDatabase, которая указывает на псевдоним BDE. Во время выполнения мой пакет загружается динамически, и в пакете вызывается метод, который создает TQuery и открывает его, заполняет объект возвращенными данными, а затем возвращает объект в основное приложение. TQuery использует TDatabase в основном приложении для подключения к базе данных. Все это работает нормально, но когда я закрываю приложение, я получаю сообщение о нарушении прав доступа: «Проект C:...GUI.exe выдает ошибку с сообщением о нарушении прав доступа по адресу 0x7c9102db: запись адреса 0x00040ffc». Процесс остановлен. Используйте «Шаг» или «Выполнить», чтобы Продолжать". Если мой метод создает TQuery, но не открывает его, то этой ошибки не возникает. Я понятия не имею, почему это происходит! Когда я закрываю приложение, мой TQuery закрывается и освобождается в порядке, мой пакет выгружается в порядке, но после уничтожения формы возникает ошибка. Я использую Delphi 5 BTW, я старался быть кратким, поэтому, если я пропустил какую-либо полезную информацию, дайте мне знать, любая помощь будет с благодарностью получена.

Спасибо

p.s. Я знаю, что использование Delphi 5 и BDE архаично, но пока я придерживаюсь этого!


person Steve    schedule 03.11.2010    source источник


Ответы (3)


Что, если вы не освободите свой TQuery? Я имею в виду, старайтесь не освобождать свой объект TQuery, когда приложение завершает работу.

person heximal    schedule 03.11.2010
comment
Хорошо, я только что попробовал это, но это не имеет значения, ошибка все еще возникает - person Steve; 03.11.2010
comment
Принадлежит ли TQuery другому компоненту? Или создан как Qry := TQuery.Create(nil)? Если бывший - person Gerry Coll; 03.11.2010
comment
Он никому не принадлежит, я создаю его с нулевым владельцем, как вы показали (поскольку класс, в котором он находится, не является производным от TComponent) - person Steve; 03.11.2010

Это произошло со мной, когда я использовал dbExpress, раздел финализации срабатывал перед деструктором модуля данных, когда приложение было Abort()ed, и это вызывало много головной боли.

Итак, я предполагаю, что

  • Драйвер соединения BDE (или какой-либо другой ресурс) завершается перед уничтожением того, что его использует, поэтому дважды пытается завершить соединение.

Я говорю «драйвер», потому что они обычно загружаются/инициализируются только по запросу, поэтому он не будет ошибкой, если его не использовать. Так что, возможно, когда ваш пакет выгружается, он финализирует драйверы.

Попробуй это:

  • загрузите свой пакет,
  • использовать TQuery, содержащийся в пакете,
  • разгрузить пакет,
  • использовать другой TQuery, созданный в основном приложении,

и посмотрите, работает ли это, не вызывая исключений. Если это не сработает, то я думаю, что могу быть прав, и мы попытаемся выяснить, как заставить это работать.

Бог благословил!

person Trinidad    schedule 03.11.2010
comment
Я только что попытался создать и использовать другой tquery после выгрузки моего пакета, но запрос работал нормально, и AV все еще возникал при закрытии приложения. - person Steve; 03.11.2010
comment
Я обнаружил, что если я подключаю свой TQuery к TDatabase внутри пакета, ошибка не возникает, если у меня также нет TDatabase в приложении, которое открывается. - person Steve; 03.11.2010

Похоже на проблему с порядком инициализации/финализации юнита. Обычно это определяется порядком модулей в списках использования и тем, какие пакеты требуются вашему пакету.

Лучший способ попытаться решить эту проблему — отладить Delphi с помощью Delphi, или вашего пакета с помощью .EXE.
Последнее важно, потому что старые версии Delphi не всегда находят символы для ваш пакет, если вы начнете отладку с вашим EXE.

Шаги

  1. Запустите Delphi, который не содержит вашего пакета
  2. Загрузите свой пакет в Delphi
  3. Установите хост вашего пакета в Delphi
  4. Скомпилируйте пакет с полной отладочной информацией и включите опцию «отладка DCU».
  5. Запустите ваш пакет (теперь он должен загрузить Delphi, а затем ваш пакет)
  6. Завершить Дельфи
  7. Наблюдайте за стеком вызовов, когда происходит AV

Возможно, вы захотите установить точки останова для просмотра порядка инициализации/финализации (см. разделы отладки-инициализации-и-финализации/" rel="nofollow">этот пост, ссылки и комментарии для его обсуждения).

Затем поиграйтесь со списками использования и разделами требований к пакетам.

--jeroen

person Jeroen Wiert Pluimers    schedule 03.11.2010
comment
Хотя замечание об инициализации/финализации кажется правильным, отладка Delphi с помощью метода Delphi работает при попытке найти ошибки во время разработки, которые происходят в среде IDE. Здесь он говорит о загрузке пакетов во время выполнения (например, dll), то есть во время работы приложения. Это не имеет ничего общего с отладкой компонентов Delphi. - person Trinidad; 04.11.2010
comment
У меня сложилось впечатление, что пакеты связаны со временем разработки. Техника отладки одинаково хорошо работает при отладке пакетов во время выполнения. - person Jeroen Wiert Pluimers; 04.11.2010