Безопасно ли возвращать std::wstring из DLL?

Согласно некоторым старым вопросам Stackru ( невозможно передать std::wstring через DLL, C++ DLL возвращает указатель на std::list;), для C++ DLL небезопасно возвращать std::wstring потому что нет гарантии, что основная программа имеет такое же определение std::wstring и, следовательно, это может привести к аварии.

Однако, в http://en.cppreference.com/w/cpp/string/basic_string, кажется, std::wstring может использоваться взаимозаменяемо с WCHAR массив сейчас:

(Начиная с C++11) Элементы basic_string хранятся непрерывно, то есть для basic_string s, &*(s.begin() + n) == &*s.begin() + n для любого n в [0, s.size()) или, что эквивалентно, указатель на s[0] может быть передан в функции, которые ожидают указатель на первый элемент массива CharT[].

Я проверил это, пройдя &s[0] к функции WINAPI, которая ожидала WCHAR* буфера и оказалось работать (std::wstring был правильно заполнен результатами WINAPI). Так как std::wstring по-видимому, можно рассматривать как WCHAR Теперь я решил вернуться к этому вопросу: std::wstring безопасно вернуться из DLL? Почему или почему нет?

1 ответ

Решение

Ничего не изменилось в отношении передачи объектов C++ через границы DLL. Это по-прежнему не разрешено по той же причине, что и раньше. Модуль на другой стороне границы может иметь другое определение класса.

Дело в том, что &s[0] допустимый модифицируемый указатель на символьный массив на самом деле не актуален. Потому что std::basic_string это намного больше, чем просто массив символов.

Помните, что каждая реализация std::basic_string может иметь различную внутреннюю память. Может иметь другую реализацию для operator[], Может быть выделено из другой кучи. И так далее.

Я думаю, можно с уверенностью предположить, что никогда не будет допустимо передавать объекты C++ через общие границы DLL. Это возможно только в том случае, если вы гарантируете, что обе стороны границы связаны с одним и тем же экземпляром времени выполнения.

Другие вопросы по тегам