указатель на таблицу виртульных функций и DLL
От: seafresh  
Дата: 14.11.06 12:57
Оценка:
есть DLLf в которой периодически создаются объекты ClassA и его производных.
В самом ClassA и его производных есть виртуальные функции, в частности деструктор.
Проблема возникает когда DLLf выгруженна из памяти (периодически и это происходит).
Если в этот момент вызывать виртуальные функции объекта, который был создан в DLLf (а объекты данного типа создаются в том числе и самим приложением, и другими DLLx) происходит исключение [доступ по чтению], т.к. таблицы уже не существует. Перенос реализации ClassA и его производных в обособленную DLLs проблемы не решает.
В качестве решения я вижу только определение типа производного класса, создание локальной копии самими приложением и удаление полученного объекта при гарантированном присуствии, в адресном пространстве, DLLf, которая его породила.
Если есть другие варинаты с удовольствием выслушаю.
Государство должно защищать свободу и право, в этом его оправдание.
Re: указатель на таблицу виртульных функций и DLL
От: Ivan Россия www.rsdn.ru
Дата: 14.11.06 13:22
Оценка: 2 (1)
Здравствуйте, seafresh, Вы писали:

S>Если есть другие варинаты с удовольствием выслушаю.

не давать модулю выгрузиться пока есть живые объекты.
самый простой вариант — вызывать LoadLibrary в конструкторе (при создании), FreeLibrary в деструкторе (при разрушении) экземпляра. Более правильный — сделать что-то типа DllCanunloadNow и свой счетчик ссылок модуля. Не выгружать модуль пока DllCanUnloadNow не вернет true. При создании объектов увеличивать счетичк ссылок модуля, при разрушении уменьшать. DllCanUnloadNow возвращает true при нулевом счетчике ссылок модуля. Так реализуются COM серверы в библиотеке ATL, при создании компонента увеличивается счетчик ссылок модуля (_Module.Lock()), при разрушении уменьшается (_Module.Unlock()).
И еще один вариант — использовать COM , это позволит эффективно использовать экзмепляры классов/компонентов, переложив множество технических деталей на инфраструктуру COM, в частности вопросы выгрузки модуля.
Re[2]: указатель на таблицу виртульных функций и DLL
От: seafresh  
Дата: 14.11.06 20:27
Оценка:
Здравствуйте, Ivan, Вы писали:

I>Здравствуйте, seafresh, Вы писали:


I>не давать модулю выгрузиться пока есть живые объекты.

I>самый простой вариант — вызывать LoadLibrary в конструкторе (при создании), FreeLibrary в деструкторе (при разрушении) экземпляра. Более правильный — сделать что-то типа DllCanunloadNow и свой счетчик ссылок модуля. Не выгружать модуль пока DllCanUnloadNow не вернет true. При создании объектов увеличивать счетичк ссылок модуля, при разрушении уменьшать. DllCanUnloadNow возвращает true при нулевом счетчике ссылок модуля. Так реализуются COM серверы в библиотеке ATL, при создании компонента увеличивается счетчик ссылок модуля (_Module.Lock()), при разрушении уменьшается (_Module.Unlock()).

Хороший вариант, но в данном случае, я не уточнил, что сами объекты очень "легкие", что-то типа событий с данными, а вот модули "тяжелые", объемные и разнородные, есть такие, которые работают напрямую с устройствами ввода и т.п. Т.е. возможность держать их просто ради событий потребует, как минимум, серьезной их переработки. К тому-же скорость создания этих объектов (в пике порядка 6-7 сотен в секунду) не слишком стыкуется синхронизирующими функциями на уровне системы.

I>И еще один вариант — использовать COM , это позволит эффективно использовать экзмепляры классов/компонентов, переложив множество технических деталей на инфраструктуру COM, в частности вопросы выгрузки модуля.


COM хорошая вещь, но для меня, в данном случае, это слишком медленно, плохо переносимо и противоречит требованиям к приложению.
Государство должно защищать свободу и право, в этом его оправдание.
Re: указатель на таблицу виртульных функций и DLL
От: Аноним  
Дата: 14.11.06 22:50
Оценка:
Здравствуйте, seafresh

Наивный вопрос: а почему выгружается ваша длл? Всю жизнь программы пишу и пока у меня ничего само не выгружалось. Если начнёт — мой первый вопрос будет "с какой стати", а не "как боротся". Боротся же можно сделав лишний вызов LoadLibrary в клиенте (ну и для порядка — FreeLibrary, когда он exits).

Я не прав?
Re[2]: указатель на таблицу виртульных функций и DLL
От: seafresh  
Дата: 15.11.06 04:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, seafresh


А>Наивный вопрос: а почему выгружается ваша длл? Всю жизнь программы пишу и пока у меня ничего само не выгружалось. Если начнёт — мой первый вопрос будет "с какой стати", а не "как боротся". Боротся же можно сделав лишний вызов LoadLibrary в клиенте (ну и для порядка — FreeLibrary, когда он exits).


А кто сказал, что оно само выгружается?

А>Я не прав?


В данном случае нет, каждый такой модуль может быть предназначен для работы с физическим устройством, от обычных DirectShow, специализированных плат видеозахвата с специфическими драйверами и сетевых камер до различных устройств управления и визуализации.
Типов устройств поддерживается, даже на данной момент, десятки. Все они могут генерировать различные события, при этом конфигурация системы может динамически изменяться на лету, естественно совершенно не случайно, т.е. не по фазам луны ака "с какой стати", а по событиям-же, либо действиям пользователя. Тем не менее события обрабатываются собственно приложением и не синхронно с модулями, т.к. это чрезвычайно трудно реализуемо, да и не требуется. При этом все события должны быть обработонны и удаленны, даже если модуль уже удален из адрес.простр., это стандартная ситуация в нашей системе. Собственно до этого момента все давно работало через специфический объект (не экземлпяр класс), но он был не очень удобен в использовании.
В связи с этим было принято решение заменить его на класс и производные от него. Я развернуто объяснил?
Государство должно защищать свободу и право, в этом его оправдание.
Re: указатель на таблицу виртульных функций и DLL
От: Garrett Россия  
Дата: 15.11.06 08:27
Оценка:
Здравствуйте, seafresh, Вы писали:

S>есть DLLf в которой периодически создаются объекты ClassA и его производных.

S>В самом ClassA и его производных есть виртуальные функции, в частности деструктор.
S>Проблема возникает когда DLLf выгруженна из памяти (периодически и это происходит).
S>Если в этот момент вызывать виртуальные функции объекта, который был создан в DLLf (а объекты данного типа создаются в том числе и самим приложением, и другими DLLx) происходит исключение [доступ по чтению], т.к. таблицы уже не существует. Перенос реализации ClassA и его производных в обособленную DLLs проблемы не решает.

А если и создание экземпляров ClassA перенести в DLLs, и не отключать DLLs до конча работы?
в борьбе со здравым смыслом победа будет за нами!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.