![]() |
|
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]()
|
|
| Avers |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
У меня имеется пакет bpl (Пакет1) и приложение, загружающее ("вручную") Пакет1.
Получение интерфейса происходит через экспортируемую процедуру, как описано в конце этой темы (сама тема особого интереса не представляет и к делу не имеет отношения). В пакете хранится переменная-указатель на создаваемый экземпляр некоторой формы. В модуле пакета (единственном) есть код:
При выгрузке пакета (вручную из приложения)
Все нормально. Но при завершении программы вознкает ошибка.... Воспользовался EuricaLog - выяснил, что ошибка из RTL100. В графе "модуль/процедура" написано _IntfClear В чем может быть причина ошибки??? И как поступить со следующей функцией, при выгрузке пакета:
где CProcName - некоторая константа. Это сообщение отредактировал(а) Avers - 16.12.2008, 17:34 --------------------
Born to be wild |
||||||
|
|||||||
| Bose |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1458 Регистрация: 5.3.2005 Где: Riga, Latvia Репутация: 8 Всего: 51 |
Avers, а интерфейс где-нибудь освобождается?
|
|||
|
||||
| Avers |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Bose, подумал и об этом. И просто убрал данную переменную, т.е. код стал следующим:
В приложении интерфейс просто присваивается nil перед выгрузкой пакета. Добавлено через 11 секунд Не помогло :( --------------------
Born to be wild |
|||
|
||||
| CodeMonkey |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Вышу по тексту что там? Кто вызвал _IntfClear? _IntfClear - это очистка интерфейса. Т.е.
Иными словами - вы выгрузили пакет, но у вас где-то осталась ссылка на интерфейс из этого пакета. Перед выгрузкой пакета вам нужно явно освободить все переменные. Посмотрите внимательно, не появились ли где у вас временные переменные. Например: Интерфейсы.Access Violation в _IntfClear для TComponent. Приведите пример, как вы получаете и используете интерфейсы. Добавлено через 2 минуты и 51 секунду Ещё обратите внимание: для TForm у вас есть смешение и ручного управления жизненным циклом (MyForm.Free) и автоматического (function GetMyFormInt: IMyFormInt). Не запутайтесь тут. Как бы не получилось так, что сперва удаляется форма вызовом MyForm.Free, а только потом освобождается её интерфейс. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||
|
|||||
| MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
а накой убиваешь еще раз форму, если интерфейс ее прибьет, когда его счетчик обнулиться? -------------------- There are always someone smarter than you... |
|||
|
||||
| Avers |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Не поверите - ничего. В стеке (EurikaLog'а) запись только о данном модуле. Добавлено через 3 минуты и 28 секунд
Если данную строчку убрать, то шибка становится еще жестче=))) вылетает с завидной регулярностью (пару сообщений в секунду) до тех пор, пока не будет убит процесс (само приложение). Добавлено через 5 минут и 39 секунд Есть одно решение - не выгружать пакет, тем более, что программу могут запустить еще раз, либо другую программу, которая использует этот же пакет..... Тогда и ошибок никаких не вылетает. Но это не есть выход... :( Конечно, 700 Кб памяти - в наше время ничто, но все же... не хочется, чтобы пакет висел в памяти до самого завершения работы машины... --------------------
Born to be wild |
|||
|
||||
| CodeMonkey |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Включите Use Debug DCUs и Stack Frames для пакета и exe и сделайте обоим Build. P.S. Кстати, было бы также неплохо выключить run-time пакеты в exe и убрать всё из requires пакета. Плюс поменять LoadPackage/UnloadPackage на LoadLibrary/UnloadLibrary. Но такое кардинальное изменение - потом. Если не получится по-другому. Вообще, в EL есть некоторые проблемы с этим делом - я уже описывал их в этом посте. Запустите под отладчиком, вызовите исключение, выпадите в отладчик - и посмотрите в окно Call Stack. Добавлено через 9 минут и 31 секунду
В обратную сторону тоже могут быть проблемы (строго говоря, вы код не покази, может у вас такой проблемы и нет, но вы всё равно рассмотрите этот сценарий). Освобождается интерфейс -> удаляется форма -> ссылка MyForm теперь указывает на мусор. Выгружается пакет -> выполняются секции finalization -> вызывается десктруктор MyForm, которая является битой ссылкой. Результат: очень интересное поведение программы. Если в деструкторе TMyForm вставить MyForm := nil; то это уберёт ошибку. Плюс, вы сможете продиагностировать: освободили ли интерфейс, перед выгрузкой пакета:
Аналогично можно сделать и для других интерфейсов. P.S. Строго говоря, в деструкторе уже стоит такая проверка. Но сообщение там, мягко говоря, маловразумительное. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||||
|
|||||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Если я ничего не путаю, то COM, например, использует такую технологию: время от времени вызывает функцию, которая говорит, можно ли выгрузить сейчас эту DLL. Т.е. DLL выгружается не сразу, а как только будет освобождён последний её интерфейс. В принципе, так и надо делать по-правильному. Но лично мне тоже такой вариант не нравится - ну вот хочется мне сделать явную выгрузку. Но при этом нужно всё аккуратно реализовать. Потому что возможны проблемы как у вас - а именно: смешение ручного и автоматического управления жизненным циклом. Выгрузка DLL/пакета явно - это есть ручное управление. Использование интерфейсов - автоматическое. Реализация должна быть очень аккуратной, чтобы не напортачить в этом смешении. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| Avers |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Код, касающийся интерфейса и класса (модуль пакета):
Такие имена у интерфеса и формы в реале=)) Так я получаю интерфес в приложении:
Еще раз повторюсь - выгрузку пакета пробовал разную, так же много раз правил часть финализации в пакете. Имхо, дело в экспортируемой функции.... не нравится она мне. --------------------
Born to be wild |
||||
|
|||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Что стоит в ... между:
??? Если в многоточиях ничего не стоит, то уберите MyForm.free и перебилдите всё. Проверьте. Функция здесь ни при чём. У вас где-то имеет место быть неаккуратное обращение с интерфейсом. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| Avers |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Между есть обращение к функции и свойству интерфейса. ... Пробовал.... Ошибки летять одна за одной.... Где-то что-то проглядел. Чем больше бьюсь над проблемой, тем больше убеждаюсь, что решение оч. простое. --------------------
Born to be wild |
|||
|
||||
| CodeMonkey |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Подробнее опишите. Пока не ясно ничего. Какая ошибка (исключение? Класс?)? В какой момент вылетает (во время работы? после выгрузки? в момент выхода?)? Сообщение? Содержимое Call Stack? Что EurekaLog говорит? Почему мы должны всё это угадывать? Может код покажете? Давайте вы всё же сделаете: а). Включите Use Debug DCUs и Stack Frames для пакета и exe и сделайте обоим Build. Запустите под отладчиком, вызовите исключение (выйдите из программы), выпадите в отладчик - и посмотрите в окно Call Stack среды IDE (View/Debug windows/Call Stack). Сообщите сюда его содержание. б). Убираете MyForm.Free, убираете все лишние действия между GetInterfaceFunction и об-nil-ением интерфейса - чтобы код был в точности такой, какой вы сюда выложили. Всё перебилдите и проверите на работоспособность. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
| Avers |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Т.е. ошибки возникают при завершении работы приложения. Сама выгрузка пакета происходит вполне корректно. Ошибка: Access violation at address 2000A264 in module 'rtl100.bpl'. Read of address 05580C9C. EL Пишет подробнее: 2.3 Module Name : rtl100.bpl - (CodeGear Component Package) 2.4 Module Version: 11.0.2627.5503 2.5 Type : EAccessViolation 2.6 Message : Access violation at address 2000A264 in module 'rtl100.bpl'. Read of address 05580C9C. 2.7 ID : F599 Use Debug DCUs и Stack Frames - включил. Мало чего дало. Пишет следующее: :2000ф264 TClassHelperBse._Create + $C :7c816fd7 kernel32.RegisterWaitForInputIdle + 0x49 И все. Причем, в данном случае ошибка вылетела при запуске (!!!). Хотя, раньше вылетала при завершении...... Че-то ваще ни че не понимаю....... Дело вот еще в чем. Раньше я получал интерфейс, получая перед этим класс формы, создавая форму в приложении.... Тогда при выгрузке все было нормально. --------------------
Born to be wild |
|||
|
||||
| CodeMonkey |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
В такой схеме интерфейс не использовался для управления жизнью формы. Тут и нет места, чтобы напутать. Это вы сейчас какой случай описали? Если это начальная ситуация из самого вопроса: то почему ошибки, если раньше вы говорили про ошибку? Если же это ответ на мой вопрос про поведение после убирания MyForm.Free, то где же тут:
Если способы а и б из моего предыдущего поста не помогут, то есть ещё вариант отключить на время тестов пакеты. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
||||
|
|||||
| Avers |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.6.2008 Где: 26rus Репутация: нет Всего: нет |
Окзалось, что - не выгружать пакет - есть единственное решение. 1. Закоментил строки
2. Проверил, остается ли пакет в памяти, ибо навмеревался попытаться выгрузить его после завершения программы. Оказалось, что пакета в памяти нет..... почему, не понимаю. Но факт, кто каждый раз при запуске приложения при таком коде:
Пакет загружается заново. Напрашивается вывод, что при завершении приложения винда пыталась выгрузить пакет (что она в общем-то теперь и делает) и из-за этого ошибка и возникала..... Странно, потому что пакет загружается вручную. --------------------
Born to be wild |
||||
|
|||||
![]()
|
| Правила форума "Delphi: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |