我的理解是,暴露std::string跨越DLL边界获取或返回stl容器(例如)的函数可能会导致问题,因为2个二进制文件中这些容器的STL实现存在差异.但是导出类这样的类是否安全:
class Customer
{
public:
wchar_t * getName() const;
private:
wstring mName;
};
Run Code Online (Sandbox Code Playgroud)
如果没有某种破解,mName将无法被可执行文件使用,因此它无法在mName上执行方法,也无法构造/破坏此对象.
我的直觉是"不要这样做,这是不安全的",但我无法找出一个很好的理由.
这不成问题.因为它被更大的问题所取代,所以你不能在代码中创建该类的对象,该代码存在于包含该类代码的模块之外的模块中.另一个模块中的代码无法准确知道所需的对象大小,它们对std :: string类的实现可能会有所不同.正如声明的那样,它也会影响Customer对象的大小.即使是相同的编译器也无法保证这一点,例如混合优化和调试这些模块的构建.虽然这通常很容易避免.
因此,您必须为Customer对象创建一个类工厂,该工厂位于同一个模块中.然后自动暗示任何触及"mName"成员的代码也存在于同一模块中.因此是安全的.
接下来的步骤是不暴露客户,而是暴露纯粹的抽象基类(又称接口).现在,您可以阻止客户端代码创建Customer实例并开始关闭.而且你也可以轻而易举地隐藏std :: string.基于接口的编程技术在模块互操作场景中很常见.也是COM采取的方法.