关于c ++:DLL和STL以及静态数据(哦,我的!)

DLLs and STLs and static data (oh my!)

好啊。。。。。我已经阅读了所有关于相关问题的文章,以及一些关于一天的谷歌搜索的MSDN文章。

对于这个问题,当前的"最先进"回答是什么:

我使用VS 2008,C++非托管代码。我有一个解决方案文件,其中包含相当多的DLL和相当多的Exe。只要我完全控制构建环境,使所有的部件和部件都用相同的标志构建,并且使用相同的运行时库,并且没有人有静态链接的CRT库,我可以传递STL对象吗?

这看起来应该没问题,但是取决于你读的是哪篇文章,有很多恐惧、不确定和怀疑。

我知道在后台生成静态数据的模板有各种各样的问题(每个DLL都会得到自己的副本,这会导致心痛),但是常规的旧STL呢?


只要它们都使用完全相同版本的运行时DLL,STL就应该没有问题。但一旦你有了几个,他们会使用不同的堆-导致无穷无尽的麻烦。


我们成功地在我们的应用程序中传递STL对象,它由几十个DLL组成。为了确保它正常工作,我们在每个构建中运行的自动化测试之一就是验证所有项目的设置。如果添加新项目并对其进行错误配置,或者破坏现有项目的配置,则生成将失败。

我们检查的设置如下。注意,并非所有这些都会导致问题,但我们会检查它们的一致性。

γ定义

1
2
3
4
5
6
_WIN32_WINNT
STRICT
_WIN32_IE
NDEBUG
_DEBUG
_SECURE_SCL

编译器选项

1
2
3
DebugInformationFormat
WholeProgramOptimization
RuntimeLibrary


我们在应用程序中使用STL集合,并将它们传递给不同DLL中的方法(通常作为引用)。这不会造成任何麻烦。

唯一的问题是一个dll分配内存,另一个dll试图删除内存。这只不过是坏消息,但我不知道为什么。然而,它似乎只是调试版本上的一个问题(在报告的地方),但仍然可以在发布版本上工作。我说过无论在哪里遇到这个问题,我都会解决它。

如果我在编写第三方库,我会考虑在API中使用stl参数。以前(VC6),我们必须使用OCI(Oracle C API),而不是OCI(Oracle C++ API),因为它只与微软STL实现一起工作,并且我们使用STLPART。当然,如果您允许您的客户机使用自己的STL实现来构建库,这不是一个问题。