gpt4 book ai didi

c++ - 从 dll 返回 std::string/std::list

转载 作者:IT老高 更新时间:2023-10-28 23:12:33 30 4
gpt4 key购买 nike

简短的问题。

我刚刚得到了一个我应该与之交互的 dll。Dll 使用来自 msvcr90D.dll(注意 D)的 crt,并返回 std::strings、std::lists 和 boost::shared_ptr。运算符 new/delete 不会在任何地方重载。

我假设 crt mixup(发布版本中的 msvcr90.dll,或者如果使用更新的 crt 重新构建组件之一等)最终会导致问题,并且应该重写 dll 以避免返回任何可能调用 new/删除(即任何可以在我的代码中对在 dll 中分配的内存块(可能使用不同的 crt)调用 delete 的东西)。

我是对还是错?

最佳答案

要记住的主要事情是 dll 包含 code 而不是 memory。分配的内存属于进程(1)。当您在流程中实例化一个对象时,您将调用构造函数代码。在该对象的生命周期中,您将调用其他代码(方法)来处理该对象的内存。然后当对象消失时,调用析构函数代码。

STL 模板不是从 dll 中显式导出的。代码静态链接到每个 dll 中。因此,当在 a.dll 中创建 std::string s 并将其传递给 b.dll 时,每个 dll 将具有 string::copy 方法的两个不同实例。 a.dll中调用的copy调用a.dll的copy方法...如果我们在b.dll中使用s并调用copy,b.dll中的copy方法将被调用。

这就是为什么在西蒙的回答中他说:

Bad things will happen unless you can always guarantee that your entire set of binaries is all built with the same toolchain.

因为如果由于某种原因,a.dll 和 b.dll 之间的字符串 s 的拷贝不同,就会发生奇怪的事情。更糟糕的是,如果 a.dll 和 b.dll 之间的字符串本身不同,并且其中的析构函数知道清除另一个忽略的额外内存……您可能很难追踪内存泄漏。可能更糟……a.dll 可能是针对完全不同版本的 STL(即 STLPort)构建的,而 b.dll 是使用 Microsoft 的 STL 实现构建的。

那你该怎么办?在我们工作的地方,我们严格控制每个 dll 的工具链和build设置。所以当我们开发内部 dll 时,我们可以自由地传输 STL 模板。由于有人没有正确设置他们的项目,我们仍然会在极少数情况下出现问题。但是,我们发现 STL 的便利性值得偶尔出现的问题。

对于将 dll 暴露给第 3 方,这完全是另一回事。除非您想严格要求来自客户端的特定build设置,否则您将希望避免导出 STL 模板。我不建议严格强制您的客户具有特定的build设置...他们可能有另一个第三方工具,希望您使用完全相反的build设置。

(1) 是的,我知道静态和局部变量在 dll 加载/卸载时被实例化/删除。

关于c++ - 从 dll 返回 std::string/std::list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3564985/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com