У меня есть два экспортированных dll класса A и B. Объявление содержит функцию, которая использует std::vector в своей сигнатуре, например:
class EXPORT A{
// ...
std::vector<B> myFunction(std::vector<B> const &input);
};
(EXPORT - это обычный макрос, который должен быть установлен на _declspec (dllexport)/_ declspec (dllimport) соответственно.)
Чтение проблем, связанных с использованием классов STL в интерфейсе DLL, я собираю в резюме:
-
Использование std::vector в интерфейсе DLL потребует, чтобы все клиенты этой DLL были скомпилированы с той же версией одного и того же компилятора, потому что контейнеры STL не совместимы с бинарными. Хуже того, в зависимости от использования этой DLL-клиентами совместно с другими DLL-интерфейсом, "нестабильный" DLL-API может разорвать эти клиентские приложения при установке обновлений системы (например, пакетов Microsoft KB) (действительно?).
-
Несмотря на вышесказанное, если требуется, std::vector можно использовать в DLL API, экспортируя
std::vector<B>
как:template class EXPORT std::allocator<B>; template class EXPORT std::vector<B>;
хотя это обычно упоминается в контексте, когда вы хотите использовать std::vector в качестве члена A (http://support.microsoft.com/kb/168958).
-
В следующей статье технической поддержки Microsoft обсуждается, как получить доступ к std::vector объектам, созданным в DLL, с помощью указателя или ссылки из исполняемого файла (http://support.microsoft.com/default.aspx?scid=kb; EN-US; Q172396). Вышеупомянутое решение использовать
template class EXPORT ...
также применимо. Однако недостаток, суммированный под первой точкой, кажется, остается. -
Чтобы полностью избавиться от проблемы, нужно было бы обернуть std::vector и изменить подпись
myFunction
, PIMPL и т.д.
Мои вопросы:
-
Является ли приведенное выше резюме правильным, или я пропустил здесь что-то существенное?
-
Почему компиляция моего класса 'A' не генерирует предупреждение C4251 (класс 'std::vector < _Ty > ' должен иметь dll-интерфейс, который будет использоваться клиентами...)? У меня нет предупреждений о компиляторе, и я не получаю предупреждения об использовании std::vector в
myFunction
в экспортированном классе A (с VS2005). -
Что нужно сделать, чтобы правильно экспортировать
myFunction
в A? Можно ли просто экспортироватьstd::vector<B>
и B распределитель? -
Каковы последствия возврата std::vector по значению? Предполагая исполняемый файл клиента, который был скомпилирован с другим компилятором (-версия). Сохраняется ли проблема при возврате значения, когда вектор скопирован? Я думаю да. Аналогично, для передачи std::vector в качестве постоянной ссылки: мог ли доступ к
std::vector<B>
(который мог быть создан исполняемым файлом, скомпилированным с другим компилятором (-версия)), приводит к проблемам вmyFunction
? Я думаю, да еще раз. -
Является ли последняя точка маркера, указанная выше, действительно единственным чистым решением?
Большое спасибо за ваши отзывы.