dorador
Гость
|
|
« : 01-03-2004 09:59 » |
|
Есть некий класс A, его наследники B и C создаются (new) в exe-файле и их указатели запихиваются в vector. К exe подключается dll (LoadLibrary), в которой создается (new) наследник D класса A. Указатель на D передается из dll в exe и тоже запихиваются в vector. После этого я работаю с динамическим массивом указателей на объекты класса A, независимо от того были они созданы в exe или в DLL. Честно говоря, я очень удивился, когда это сработало. У меня это получилось случайно. Я собирался делать отдельный vector в exe и dll. Может кто объяснит почему это работает? и при каких условиях это работать не будет?
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #1 : 01-03-2004 10:45 » |
|
А что именно удивляет? Во-первых, .dll размещается в том же адресном пространстве, что и .exe. Во-вторых, экземпляры класса, созданные посредством new, в любом случае размещаются в динамической области ("куче"). А то, что .dll способен передать в.exe указатель, и подавно не должно удивлять. Если бы .dll не могли даже этого, вряд ли они вообще были бы нужны.
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #2 : 01-03-2004 13:05 » |
|
Проблемы могут возникнуть если обьект создается в dll, а у даляется в программе, загрузившей dll Возникают они из-за того, что у програмы и у dll свои run-time либы, а память, выделенная одной runtime не может быть освобождена другой, это проблема решается динамическим подглючением runtime'a (в опциях линкера) У тебя рантайм не статически слинкован, поэтому все ок.
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #3 : 01-03-2004 13:17 » |
|
То есть, у меня это получилось, потому что RTL линкуется с DLL и с exe динамически, следовательно у них общая куча, с которой и работает new. То есть, если таким образом размещать переменные (структуры, классы), то указатели на них можно свободно передавать и использовать как в exe, так и в любой загруженной DLL :?:
|
|
|
Записан
|
|
|
|
Alf
Гость
|
|
« Ответ #4 : 01-03-2004 13:26 » |
|
Уверен, что проблем не будет ни при каких условиях, если объекты будут уничтожаться в той же части программы, в которой создавались. Даже если кучи разные, вряд ли это повлияет на работу с объектом через указатель.
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #5 : 01-03-2004 13:59 » |
|
Либо динамическая линковка, либо удалять обьекты там же где создавались
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #6 : 01-03-2004 15:26 » |
|
а если я указатель на статическую переменную передам? Получается что в рамках одного процесса любой указатель РАБОТАЕТ, независимо от того, в каком модуле был создан объект :?: И действительно, что тут удивительного. Наверное, меня смутило, что это был класс и выполнялось обращение из exe к его функциям-членам, определенным в DLL.
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #7 : 01-03-2004 21:08 » |
|
Конечно работает, в одном процессе все указатели локальные и все замечательно статическая переменная отличается от обычной только временем жизни и распологается она в куске памяти для статических переменных
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #8 : 30-03-2004 14:31 » |
|
Рассказал я тут некоторым людям что сделал (см. выше) и они меня смутили :oops: : будет ли это работать если exe и dll откомпилированы разными компиляторами или с разным выравниванием :?:
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #9 : 31-03-2004 08:01 » |
|
Проверил: откомпилировал exe под VC6, а dll под VC7 - не работает
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #10 : 31-03-2004 09:24 » |
|
А что значит "указатель работает" :?:
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #11 : 31-03-2004 09:46 » |
|
А что значит "указатель работает" :?: имеется в виду указатель на функцию - значит что управление передается куда задумано а не в никуда
|
|
|
Записан
|
|
|
|
Chaa
|
|
« Ответ #12 : 31-03-2004 10:09 » |
|
Обрати внимание на атрибуты __declspec( dllexport ) и __declspec( dllimport ) для классов. Это должно помочь при работе с разными компиляторами или с разным выравниванием. Правда набор компиляторов будет ограничен VC.
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #13 : 31-03-2004 12:50 » |
|
А как ты получаешь этот указатель ?
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #14 : 31-03-2004 14:34 » |
|
А как ты получаешь этот указатель ? делаю new в DLL а потом передаю его в exe
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #15 : 31-03-2004 14:38 » |
|
уточняю что перестает работать не сам указатель на объект, он срабатывает и я перехожу в функцию базового класса, а когда пытаюсь по указателю на функцию наследуемого класса перейти на нее, то перехожу в никуда
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #16 : 31-03-2004 15:43 » |
|
Что то я не понимаю что ты вообще пытаешься сделать, давай код
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #17 : 01-04-2004 07:47 » |
|
Я пытаюсь делать то что написал в 1-м сообщении данной темы Есть некий класс A, его наследники B и C создаются (new) в exe-файле и их указатели запихиваются в vector. К exe подключается dll (LoadLibrary), в которой создается (new) наследник D класса A. Указатель на D передается из dll в exe и тоже запихиваются в vector. После этого я работаю с динамическим массивом указателей на объекты класса A, независимо от того были они созданы в exe или в DLL.
тогда я компилировал dll и exe в VC6 - все работало без проблем теперь я откомпилировал dll в VC7 и получил следующее: вызов невиртуальной функции базового класса А выполняется, а вот с виртуальными функциями (перекрытыми в классе D) проблемы - ошибка доступа
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #18 : 01-04-2004 08:32 » |
|
с какими параметрами скомпилены dll и exe ? как CRT поключена ?
|
|
|
Записан
|
|
|
|
dorador
Гость
|
|
« Ответ #19 : 01-04-2004 09:23 » |
|
как CRT поключена ?
Multi-threaded Debug DLL (/MDd) могу все опции показать - надо? вообще такое впечатление что адрес таблицы виртуальных функций в VC6 и VC7 в разных местах
|
|
|
Записан
|
|
|
|
|