[c++] передача объектов stl в dll

gotson

Я решил сделать интерфейс для плагинов, прогаю в ms vs 2008. Плагин экспортирует функции создания и удаления объектов класса, реализующего некоторые интерфейсы. Подразумевается написание плагинов сторонними людьми, возможно вообще с использованием gcc, итд. Так что появляется мысль отказаться от использования объектов stl в качестве параметра в методе интерфейсов (неявные внутренние операции с памятью и возможные крэши). А этого не очень бы хотелось. Какой-нибудь левый пример:
interface.h:
  
class IAlgorithm{
public:
virtual void GetSecretValues ( std::vector < float >& values ) = 0;
// как вариант - передавать по указателю *
virtual ~IAlgorithm;
}

myalgorithm.cpp:
  
class MyAlgorithm: public IAlgorithm{
public:
virtual void GetSecretValues ( std::vector < float >& values ){
values.push_back(1.f);
values.push_back(2.f);
values.push_back(3.f);
return;
};
}

plugin.cpp:
  
extern "C" __declspec(dllexport) void Create ( IAlgorithm **obj ){
*obj = new MyAlgorithm;
}

extern "C" __declspec(dllexport) void Release( IAlgorithm **obj ){
delete *obj;
}

host.cpp:
  
int main{

IAlgorithm* obj;
vector<float> values;

LoadLibrary(...);
Create(&obj);
obj->GetSecretValues(values);
Release(&obj);

return 0;
}


Судя по нагугленному:
http://social.msdn.microsoft.com/Forums/en/vclanguage/thread...
http://stackoverflow.com/questions/7533812/passing-stl-and-o...
с такого типа кодом могут быть проблемы, если хост и библиотека скомпилены с разными рантайм библиотеками.
Предлагаются варианты с экспортом специализаций stlных тимплейтов:
http://stackoverflow.com/questions/1881494/how-to-expose-stl...
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q172...
но, как я понял, для моего случая с произвольными плагинами это не очень подходит.
При этом в другом проекте в примерно похожей ситуации вроде все ок при работе с stl веторами и стрингами.
Насколько это проблема реально актуальна для, например, tuple, string, vector, pair, map? Какие есть варианты избегания подобных проблем при незначительном изменении интерфейса? Возможно с применением буста или еще чего-нибудь. (ну уж очень не хочется вектор передавать по указателю и количеству элементов)

Realist

Ну оберни vector<float> в свой тип и экспортируй его и таким интерфейсом, чтоб точно был совместим.
А вообще когда ты на эти грабли наступишь, ты ночи в дебагере проведешь, втыкая, где ты память попортил. Нету счастья. Используй float *. И то, зависит от разрядности, так что все равно можно огрести.

Maurog

Подразумевается написание плагинов сторонними людьми, возможно вообще с использованием gcc, итд.
в таком случае я бы посоветовал бы все же C-style интерфейс с типами фиксированного размера и лейаута
stl вряд ли заведется сквозь vs2008->gcc даже не столько из-за проблем с памятью, сколько из-за различных реализаций, и экспорт тут не поможет
если вы собираетесь пробрасывать float сквозь бинари, то вам нужно зафиксировать размер и лейаут, либо маршалить каким-то своим способом (например, через строки char*)
а так обычно используют типы char, int32_t, uint64_t с более менее стандартным лейаутом и фиксированным размером
опасность экспорта интерфейсов заключается в нестандартизованности и в реальной различности реализаций виртуальных таблиц (ABI) у gcc и vs2008, поэтому его применяют, закладываясь на компилятор (то есть все плагины будут скомпилированы vs2008). с интерфейсами работать проще, но они накладывают ограничения.
так что выбор за вами :D

okunek

Сериализуй и десериализуй через xml :grin:
"Наебешся и напляшешься" :)

gotson

спасибо. буду думать насколько будет актуальна такая широкая поддержка компиляторов )

gotson

ну длл другой разрядности я вроде тупо не смогу подгрузить. спс, наверное временно так и сделаю.

gotson

нет уж, спасибочки =)

Werdna

передавать параметром объекты STL ни в коем случае нельзя, ибо STL зависит от реализации.
Передавать надо только обычные типы и массивы, типа uin32_t*
Строки — только как const char* с завершающим нулём или указанным размером. Если ты передал std::string — ты вообще пипец какой мудак.

Werdna

Ещё как вариант — сделать класс-обёртку и дать её. Обёртка должна быть такой, чтобы нельзя было напрямую обратиться к реализации, но можно было за ниточки подёргать всё что надо.

elenangel

почему еще никто не сказал слово COM?

procenkotanya

в приличной компании это лучше не упоминать
inb4 "приличная компания? это ФОРУМ_ЛОКАЛ!"

apl13

Здесь не матерятся!

ava3443

буду думать насколько будет актуальна такая широкая поддержка компиляторов )
Даже зафиксировав одну версию MSVC (допустим, 2008 или 2010) и один вариант runtime-библиотеки (скажем, release при передаче STL будешь падать в случае различий в флагах компиляции _SECURE_SCL и _HAS_ITERATOR_DEBUGGING - погугли по фразе "cross-binary _HAS_ITERATOR_DEBUGGING/_SECURE_SCL mismatch"
P.S. почему кто-то может и будет пытаться играть с этими флагами описано например тут: http://blogs.warwick.ac.uk/ahazelden/entry/visual_studio_stl... (у микрософтовской имплементации stl некоторые отладочные штуки не отключаются даже в релиз сборке)
ещё почитай http://connect.microsoft.com/VisualStudio/feedback/details/3...

Serab

и один вариант runtime-библиотеки (скажем, release)
если статическая линковка рантайма, то тоже может навернуться :)

agaaaa

почему еще никто не сказал слово COM?
Почему ещё никто не предложил сменить язык?
Оставить комментарий
Имя или ник:
Комментарий: