Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to return std::wstring from a DLL?

According to some older StackOverflow questions ( Unable to pass std::wstring across DLL , C++ DLL returning pointer to std::list<std::wstring> ) it's not considered safe for a C++ DLL to return a std::wstring because there's no guarantee the main program has the same definition of std::wstring and therefore it might cause a crash.

However, in http://en.cppreference.com/w/cpp/string/basic_string , it seems std::wstring can be used interchangeably with a WCHAR array now:

(Since C++11) The elements of a basic_string are stored contiguously, that is, for a basic_string s, &*(s.begin() + n) == &*s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can be passed to functions that expect a pointer to the first element of a CharT[] array.

I've tested this by passing &s[0] to a WINAPI function that expected a WCHAR* buffer and it appeared to work (the std::wstring was correctly populated with the results of the WINAPI). So since std::wstring can apparently be treated like a WCHAR array now, I decided to revisit this question: can a std::wstring be safely returned from a DLL? Why or why not?

like image 762
cf stands with Monica Avatar asked Dec 17 '13 23:12

cf stands with Monica


1 Answers

Nothing has changed with regards passing C++ objects across DLL boundaries. That is still not allowed for the same reason as before. The module on the other side of the boundary may have a different definition of the class.

The fact that &s[0] is a valid modifiable pointer to character array is not really relevant. Because a std::basic_string is a lot more than just an array of characters.

Remember that each implementation of std::basic_string can have different internal storage. Can have a different implementation for operator[]. Can be allocated off a different heap. And so on.

I think it is safe to assume that it will never be valid to pass C++ objects across general DLL boundaries. It is only viable if you guarantee that both sides of the boundary are linked against the same runtime instance.

like image 95
David Heffernan Avatar answered Sep 28 '22 08:09

David Heffernan