![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
scroollocker |
|
||||||||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
Всем привет.
Случилась такая ситуация у меня, непонятная для меня... Вообщем прошу помощи. Есть некоторый класс - интерфейс:
В dll создаю его наследника,
Затем в той же dll создаю 2е функции, одна будет возвращать созданный в dll объект. Другая уничтожать его.
А уже в программе, которая загружает dll, используя интерфейс IDb, хочу пользоваться методами. Но, по какой-то причине, объект возвращается указывающий на какой то мусор... Вот код главной программы:
Что я делаю не так? чего я не знаю? подскажите пожалуйста *UPD - очепятался Это сообщение отредактировал(а) scroollocker - 23.8.2013, 22:51 |
||||||||
|
|||||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Гм. Что-то странное Вы делаете с указателями: это понятно; Вот это не понятно. По адресу _data размещается другой адрес, указывающий на int со значением 50... Должно быть, имелось в виду:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
scroollocker |
|
|||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
feodorv,
Да все верно, это я опечатка здесь, т.к. в программе конструкция немного помассивней. Здесь хотел показать то, что в dll в классе выделяется память под объекты. А в основной программе, данные просматриваются. Это сообщение отредактировал(а) scroollocker - 23.8.2013, 22:57 |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Dll и exe сделаны одним компилятором? С одними и теми же настройками типа вызова и упаковкой структур? GetProcAddress возвращает не NULL?
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
scroollocker |
|
|||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
borisbn,
да, оба собраны в minGW, настройки одни и те же.
Да, не NULL. Здесь пример уж слишком прост, в программе, над которой работаю, там есть методы, которые динамически работают со списками. Добавляют удаляют, получают данные. |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Но он работает? Может, дело как раз в том, что -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
scroollocker |
|
|||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
feodorv,
пример этот тоже проверял, тоже не работает. Даже не происходит вызов конструктора класса. Никак не могу понять причину. Может кто нибудь посоветует другой способ, чтобы был один интерфейс для взаимодействия с объектами, созданными в dll. Если я изменю методы, добавлю поля, чтобы не было необходимости изменять\перекомпилировать код основной программы. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Одинаковая версия компилятора для Dll и для Exe совсем не обязательно. Достаточно использовать COM совместимые интерфейсы. У меня студия прекрасно работает с объектами созданными в билдере и наоборот. При передаче объектов, просто нужно соблюдать несколько простых правил.
1) В каком модуле выделил, в том и освободил. 2) Передавать в методы объекта можно либо POD типы (с указанным выравниванием) или интерфейсы. 3) Не рекомендуется передавать тип enum, так как его размер зависит от настроек компилятора. 4) Исключения не должны покидать модуль. Если функция может сгенерить исключение, то его лучше поймать и вернуть кодом ошибки. 5) Внимательно работать со строками. Объект std::string или аналогичный не должен покидать границу модуля. Тут же со строками. Если обмениваться строками типа whar_t*/char* можно использовать функцию SysAllocString, она использует внешний менеджер памяти. Тоже самое послабление можно сделать для POD типов если объединить менеджеры памяти (общий менеджер памяти в отдельной Dll). 6) Не создавать для интерфейсов конструкторы и деструкторы. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Проверил на MS Visual C++ 6.0, работает))) Присоединённый файл ( Кол-во скачиваний: 3 ) ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
scroollocker |
|
||||||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
Код заработал. Обновил компилятор на новую версию. НО.
Программа все равно вылетает на этом месте:
Оказалось, если объявленное в dll
изменить на
программа работает нормально. feodorv, да спасибо, обновил компилятор, тоже уже стало работать. Попробуйте вызвать freeFunc(myObject); На этом месте у меня вылетает теперь =( Alexeis, Спасибо за развернутый ответ, возьму на заметку приведенные вами правила. Буду переделывать класс, в соответствии с ними. |
||||||
|
|||||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Alexeis,
7) Нельзя в интерфейсе создавать перегруженные функции 2 ТС: Я для удаления объекта добавляю в него метод destroy, который в наследнике делает delete this; IMHO удобнее -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
scroollocker |
|
||||||
![]() .{--}. Профиль Группа: Участник Сообщений: 40 Регистрация: 17.9.2010 Репутация: нет Всего: нет |
Вроде все шло хорошо, на одинаковых компиляторах было все супер... Решил попробовать на C++ Builder, и началось.... Не хочет понимать объект через интерфейс.. В связи с этим, хочу уточнить пару моментов:
Получается нельзя в созданные в dll объект ни отдавать не принимать std::string. Можно об этом пункте поподробней. Т.к. у меня существует класс - Хранилище. В него можно добавлять, удалять, изменять хранящиеся там объекты. А вот эти объекты как раз и хранят в себе std::string. Вопрос, как мне подогнать классы, чтобы можно было хранить\получать\изменять эту структуру и чтобы интерфейс был кросскомпиляторным? Интерфейс работы с БД:
сама структура UP_DATA имеет вид:
|
||||||
|
|||||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Нельзя передавать такие объекты в качестве параметров интерфейсов. Тем более структуры содержащие такие объекты. А еще тут сразу видно деструктор интерфейса. Интерфейс не должен иметь конструкторов и деструкторов, тем более виртуальных. Можно использовать char* char[] в таких структурах. Но в любом случае желательно чтобы память выделялась с одной стороны. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |