Экспорт boost::shared_ptr из dll
От: Аноним  
Дата: 14.08.09 15:18
Оценка:
Всем привет,
В DLL библиотеки есть интерфейс:
// core.h
struct type
{
   virtual ~type() {    }
   virtual std::wstring get_name() const = 0;
};

boost::shared_ptr<type> __declspec(dllexport) create_type(const std::wstring& name);


Имплементация:
// core.cpp
namespace
{
    class type_impl : public type
    {
         wstring m_name; // should be unique for connector
      public:
    explicit type_impl(const wstring& name): m_name(name){}
    virtual wstring get_name() const{ return m_name; }
     };
}
boost::shared_ptr<type> create_type(const wstring& name);


Я использую статически эту DLL из другой DLL, где создаю типы с помощью метода create_type.
При этом в релизе происходит падение при освобождении памяти. Точно по стеку понять где не получается, но если закомментировать код с вызовом create_type, то падения нет.
Самое удивительное что дебаг версия работает без проблем.

Что тут не так?
Re: Экспорт boost::shared_ptr из dll
От: Юрий Жмеренецкий ICQ 380412032
Дата: 14.08.09 15:43
Оценка:
Здравствуйте, Аноним, Вы писали:
...
А>Я использую статически эту DLL из другой DLL, где создаю типы с помощью метода create_type.
А>При этом в релизе происходит падение при освобождении памяти. Точно по стеку понять где не получается, но если закомментировать код с вызовом create_type, то падения нет.
А>Самое удивительное что дебаг версия работает без проблем.

А>Что тут не так?

Возможная причина — разные версии CRT, одна из DLL всегда имеет debug version, либо ошибки в манифестах. См. актуальные зависимости (Depends.exe; или список модулей в отладчике).
Re: Экспорт boost::shared_ptr из dll
От: Onorin Нигерия  
Дата: 14.08.09 20:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Всем привет,

А>В DLL библиотеки есть интерфейс:
А>
А>// core.h
А>struct type
А>{
А>   virtual ~type() {    }
А>   virtual std::wstring get_name() const = 0;
А>};

А>boost::shared_ptr<type> __declspec(dllexport) create_type(const std::wstring& name);
А>


А>Имплементация:

А>
А>// core.cpp
А>namespace
А>{
А>    class type_impl : public type
А>    {
А>         wstring m_name; // should be unique for connector
А>      public:
А>    explicit type_impl(const wstring& name): m_name(name){}
А>    virtual wstring get_name() const{ return m_name; }
А>     };
А>}
А>boost::shared_ptr<type> create_type(const wstring& name);
А>


А>Я использую статически эту DLL из другой DLL, где создаю типы с помощью метода create_type.

А>При этом в релизе происходит падение при освобождении памяти. Точно по стеку понять где не получается, но если закомментировать код с вызовом create_type, то падения нет.
А>Самое удивительное что дебаг версия работает без проблем.

А>Что тут не так?

Разные менеджеры памяти
Re[2]: Экспорт boost::shared_ptr из dll
От: Аноним  
Дата: 15.08.09 11:12
Оценка:
Здравствуйте, Onorin, Вы писали:

А>>Что тут не так?

O>Разные менеджеры памяти

Как с этим бороться?
Re[3]: Экспорт boost::shared_ptr из dll
От: Юрий Жмеренецкий ICQ 380412032
Дата: 15.08.09 13:03
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>>>Что тут не так?

O>>Разные менеджеры памяти

А>Как с этим бороться?


Чтобы с этим бороться — нужно знать почему они разные (если они действительно разные). Телепатические методы диагностики, как показывает практика, редко дают положительный результат, да и алгоритм поиска проблемы рискует увязнуть во множестве "если". Поэтому если ты хочешь получить ответ на свой вопрос, приведи пожалуйста дополнительную информацию, в частности:

1) Какие зависимости показывает depends.exe (с включенной опцией 'View/Full Paths') для двух DLL и EXE?
2) Если это возможно — запустить EXE под отладчиком, и инициировать падение. Нужно содержимое окна Output в отладчике полностью.
3) Наличие define'ов относящихся к shared_ptr в своем коде, особенно BOOST_SP_USE_QUICK_ALLOCATOR.

C __declspec(dllexport) все в порядке? Должно быть приблизительно так:
#ifdef USE_EXPORTS
  #define MY_API __declspec(dllexport)
#else
  #define MY_API __declspec(dllimport)
#endif

MY_API boost::shared_ptr<type> create_type(const std::wstring& name);


USE_EXPORTS должен быть опеределен только для UT с реализацией функции, клиенты должны получать объявление с dllimport. Судя по приведенному содержимому 'core.h' это не так, но возможно это не настоящий код...
Re[3]: Экспорт boost::shared_ptr из dll
От: Onorin Нигерия  
Дата: 16.08.09 09:37
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>>>Что тут не так?

O>>Разные менеджеры памяти

А>Как с этим бороться?


В двух словах, сейчас просто времени не так много на объяснение — такая проблема может проявиться если линковать Run-time статически и память в одном месте выделили, а освободить пытаемся в другом. Вот тут то мы и встаем на эти грабли.
Re[4]: Экспорт boost::shared_ptr из dll
От: Кодт Россия  
Дата: 17.08.09 09:29
Оценка:
Здравствуйте, Onorin, Вы писали:

O>В двух словах, сейчас просто времени не так много на объяснение — такая проблема может проявиться если линковать Run-time статически и память в одном месте выделили, а освободить пытаемся в другом. Вот тут то мы и встаем на эти грабли.


shared_ptr всегда удаляет с помощью родного менеджера памяти. Для этого он рядом с указателем на объект тащит указатель на функцию освобождения.
Хотя при желании можно сломать всё, что угодно, но здесь желание должно быть явным.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!
Re[5]: Экспорт boost::shared_ptr из dll
От: Юрий Жмеренецкий ICQ 380412032
Дата: 17.08.09 09:59
Оценка: 29 (1)
Здравствуйте, Кодт, Вы писали:

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


O>>В двух словах, сейчас просто времени не так много на объяснение — такая проблема может проявиться если линковать Run-time статически и память в одном месте выделили, а освободить пытаемся в другом. Вот тут то мы и встаем на эти грабли.


К>shared_ptr всегда удаляет с помощью родного менеджера памяти.

Он "запоминает" deleter для объекта, на который хранит указатель. А вот объект (наследник sp_counted_base), который содержит счетчик ссылок (и deleter) может быть удален "в другой" куче. + shared_ptr можно настроить так, что для выделения памяти под этот объект будет использоваться не стандартный аллокатор, а другой — оптимизированный (BOOST_SP_USE_QUICK_ALLOCATOR).
Re[6]: Экспорт boost::shared_ptr из dll
От: Alexander G Украина  
Дата: 17.08.09 13:46
Оценка: 6 (1)
Здравствуйте, Юрий Жмеренецкий, Вы писали:

К>>shared_ptr всегда удаляет с помощью родного менеджера памяти.

ЮЖ>Он "запоминает" deleter для объекта, на который хранит указатель. А вот объект (наследник sp_counted_base), который содержит счетчик ссылок (и deleter) может быть удален "в другой" куче. + shared_ptr можно настроить так, что для выделения памяти под этот объект будет использоваться не стандартный аллокатор, а другой — оптимизированный (BOOST_SP_USE_QUICK_ALLOCATOR).

allocate_shared расположит всё в одном месте.
Русский военный корабль идёт ко дну!
Re[7]: Экспорт boost::shared_ptr из dll
От: Юрий Жмеренецкий ICQ 380412032
Дата: 17.08.09 14:43
Оценка:
Здравствуйте, Alexander G, Вы писали:
...
AG>allocate_shared расположит всё в одном месте.
Только эта возможность отсутствует в старых версиях.
Re: Экспорт boost::shared_ptr из dll
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 19.08.09 00:38
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Я использую статически эту DLL из другой DLL, где создаю типы с помощью метода create_type.
А>При этом в релизе происходит падение при освобождении памяти.
А>Что тут не так?

Вполне возможно, что причина, как писали выше, в одновременном существовании двух heap'ов
Автор: Rakafon
Дата: 30.07.09
. Попробуйте слинковаться с библиотекой CRT динамически
Автор: Rakafon
Дата: 29.07.09
.
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
DLL
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.