| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > [C++] Доступ к объекту, созданному в dll |
| Автор: scroollocker 23.8.2013, 19:43 | ||||||||
| Всем привет. Случилась такая ситуация у меня, непонятная для меня... Вообщем прошу помощи. Есть некоторый класс - интерфейс:
В dll создаю его наследника,
Затем в той же dll создаю 2е функции, одна будет возвращать созданный в dll объект. Другая уничтожать его.
А уже в программе, которая загружает dll, используя интерфейс IDb, хочу пользоваться методами. Но, по какой-то причине, объект возвращается указывающий на какой то мусор... Вот код главной программы:
Что я делаю не так? чего я не знаю? подскажите пожалуйста *UPD - очепятался |
| Автор: feodorv 23.8.2013, 20:16 | ||
Гм. Что-то странное Вы делаете с указателями: это понятно; Вот это не понятно. По адресу _data размещается другой адрес, указывающий на int со значением 50... Должно быть, имелось в виду:
|
| Автор: scroollocker 23.8.2013, 22:53 |
| feodorv, Да все верно, это я опечатка здесь, т.к. в программе конструкция немного помассивней. Здесь хотел показать то, что в dll в классе выделяется память под объекты. А в основной программе, данные просматриваются. |
| Автор: borisbn 24.8.2013, 06:11 |
| Dll и exe сделаны одним компилятором? С одними и теми же настройками типа вызова и упаковкой структур? GetProcAddress возвращает не NULL? |
| Автор: scroollocker 24.8.2013, 13:39 | ||
| borisbn, да, оба собраны в minGW, настройки одни и те же.
Да, не NULL. Здесь пример уж слишком прост, в программе, над которой работаю, там есть методы, которые динамически работают со списками. Добавляют удаляют, получают данные. |
| Автор: feodorv 24.8.2013, 16:57 |
Но он работает? Может, дело как раз в том, что |
| Автор: scroollocker 24.8.2013, 19:26 |
| feodorv, пример этот тоже проверял, тоже не работает. Даже не происходит вызов конструктора класса. Никак не могу понять причину. Может кто нибудь посоветует другой способ, чтобы был один интерфейс для взаимодействия с объектами, созданными в dll. Если я изменю методы, добавлю поля, чтобы не было необходимости изменять\перекомпилировать код основной программы. |
| Автор: Alexeis 25.8.2013, 12:31 |
| Одинаковая версия компилятора для Dll и для Exe совсем не обязательно. Достаточно использовать COM совместимые интерфейсы. У меня студия прекрасно работает с объектами созданными в билдере и наоборот. При передаче объектов, просто нужно соблюдать несколько простых правил. 1) В каком модуле выделил, в том и освободил. 2) Передавать в методы объекта можно либо POD типы (с указанным выравниванием) или интерфейсы. 3) Не рекомендуется передавать тип enum, так как его размер зависит от настроек компилятора. 4) Исключения не должны покидать модуль. Если функция может сгенерить исключение, то его лучше поймать и вернуть кодом ошибки. 5) Внимательно работать со строками. Объект std::string или аналогичный не должен покидать границу модуля. Тут же со строками. Если обмениваться строками типа whar_t*/char* можно использовать функцию SysAllocString, она использует внешний менеджер памяти. Тоже самое послабление можно сделать для POD типов если объединить менеджеры памяти (общий менеджер памяти в отдельной Dll). 6) Не создавать для интерфейсов конструкторы и деструкторы. |
| Автор: feodorv 25.8.2013, 14:23 |
Проверил на MS Visual C++ 6.0, работает))) |
| Автор: scroollocker 25.8.2013, 19:52 | ||||||
| Код заработал. Обновил компилятор на новую версию. НО. Программа все равно вылетает на этом месте:
Оказалось, если объявленное в dll
изменить на
программа работает нормально. feodorv, да спасибо, обновил компилятор, тоже уже стало работать. Попробуйте вызвать freeFunc(myObject); На этом месте у меня вылетает теперь =( Alexeis, Спасибо за развернутый ответ, возьму на заметку приведенные вами правила. Буду переделывать класс, в соответствии с ними. |
| Автор: borisbn 25.8.2013, 22:39 |
| Alexeis, 7) Нельзя в интерфейсе создавать перегруженные функции 2 ТС: Я для удаления объекта добавляю в него метод destroy, который в наследнике делает delete this; IMHO удобнее |
| Автор: scroollocker 29.8.2013, 18:45 | ||||||
Вроде все шло хорошо, на одинаковых компиляторах было все супер... Решил попробовать на C++ Builder, и началось.... Не хочет понимать объект через интерфейс.. В связи с этим, хочу уточнить пару моментов:
Получается нельзя в созданные в dll объект ни отдавать не принимать std::string. Можно об этом пункте поподробней. Т.к. у меня существует класс - Хранилище. В него можно добавлять, удалять, изменять хранящиеся там объекты. А вот эти объекты как раз и хранят в себе std::string. Вопрос, как мне подогнать классы, чтобы можно было хранить\получать\изменять эту структуру и чтобы интерфейс был кросскомпиляторным? Интерфейс работы с БД:
сама структура UP_DATA имеет вид:
|