5

根据一些较早的 StackOverflow 问题(Unable to pass std::wstring across DLL , C++ DLL returned pointer to std::list<std::wstring>),C++ DLL 返回 a 被认为是不安全的,std::wstring因为不能保证 main程序具有相同的定义,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]给期望WCHAR*缓冲区的 WINAPI 函数对此进行了测试,并且它似乎可以工作(std::wstring正确填充了 WINAPI 的结果)。因此,既然std::wstring现在显然可以像WCHAR数组一样对待,我决定重新审视这个问题:可以std::wstring从 DLL 安全地返回 a 吗?为什么或者为什么不?

4

1 回答 1

6

在跨 DLL 边界传递 C++ 对象方面没有任何改变。由于与以前相同的原因,这仍然是不允许的。边界另一边的模块可能对类有不同的定义。

指向字符数组的有效可修改指针这一事实&s[0]并不重要。因为 astd::basic_string不仅仅是一个字符数组。

请记住,每个实现都std::basic_string可以有不同的内部存储。可以有不同的实现operator[]。可以从不同的堆中分配。等等。

我认为可以安全地假设跨一般 DLL 边界传递 C++ 对象永远不会有效。仅当您保证边界的两侧都链接到同一个运行时实例时,它才是可行的。

于 2013-12-17T23:47:17.997 回答