首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合版本的MSVCRT

混合版本的MSVCRT
EN

Stack Overflow用户
提问于 2013-11-14 15:41:19
回答 4查看 1.2K关注 0票数 7

因此,我有一个带有静态链接的MSVCRT副本的C++库。我希望任何人都能使用我的库与任何版本的MSVC运行时。实现这一目标的最佳方法是什么?

我已经对事情的处理方法非常小心了。

  1. 内存永远不会通过要释放的DLL屏障。
  2. 运行时C++对象不会跨越障碍(例如,向量、映射等)。除非他们是在屏障的那边被创造出来的)
  3. 没有文件句柄或资源句柄在屏障之间传递。

然而,我仍然有一些导致堆损坏的简单代码。

我的图书馆里有一个这样的东西:

代码语言:javascript
复制
class Foos
{
public: //There is an Add method, but it's not used, so not relevant here
    DLL_API Foos();
    DLL_API ~Foos();

private:
    std::map<std::wstring, Foo*> map;
};

Foos::~Foos()
{
    // start at the begining and go to the end deleting the data object
    for(std::map<std::wstring, Foo*>::iterator it = map.begin(); it != map.end(); it++)
    {
        delete it->second;
    }
    map.clear();
}

然后我从应用程序中使用它,如下所示:

代码语言:javascript
复制
void bar() {
    Foos list;
}

在我从任何地方调用这个函数之后,我会得到一个关于堆栈损坏的调试警告。如果我真的让它耗尽,它实际上破坏了堆栈和分段错误。

我的调用应用程序是用Visual 2012平台工具编译的。该库是使用Visual 2010平台工具编译的。

这只是我绝对不应该做的事情,还是我实际上违反了使用多个运行时的规则?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-11-14 16:44:54

内存永远不会通过DLL屏障。

但是,确实如此。很多次了。您的应用程序为类对象创建了存储,在本例中是在堆栈上。然后传递指向库中方法的指针。从构造函数调用开始。这个指针在库代码中。

在这种情况下,问题在于它没有创建正确的存储量。您可以让VS2012编译器查看类声明。它使用std::map的VS2012实现。但是,您的库是用VS2010编译的,它使用了完全不同的std::map的实现。有着完全不同的尺寸。多亏了C++11,发生了巨大的变化。

这只是完全的内存损坏,在您的应用程序中写入堆栈变量的代码将破坏std::map。相反的情况下。

跨模块边界公开C++类充满了类似的陷阱。只有当您能够保证所有的编译都使用完全相同的编译器版本和完全相同的设置时,才会考虑它。没有快捷方式,您也不能混合调试和发布构建代码。创建库以避免公开实现细节当然是可能的,您必须遵守以下规则:

  • 只公开具有虚拟方法的纯接口,参数类型必须是简单类型或接口指针。
  • 使用类工厂创建接口实例
  • 使用引用计数进行内存管理,因此总是由库发布。
  • 确定核心细节,如包装和打电话会议与硬规则。
  • 绝不允许异常穿越模块边界,只使用错误代码。

到那时,您就可以很好地编写COM代码了,还可以使用您在例如DirectX中看到的样式。

票数 9
EN

Stack Overflow用户

发布于 2013-11-14 15:59:01

map成员变量仍然是由应用程序创建的,内部数据由应用程序分配,而不是DLL (它们可能使用不同的map实现)。根据经验,不要使用DLL中的堆栈对象,在DLL中添加类似于Foos * CreateFoos()的内容。

票数 3
EN

Stack Overflow用户

发布于 2013-11-14 16:13:43

运行时C++对象不会跨越障碍(例如,向量、映射等)。除非他们是在屏障的那边被创造出来的)

你就是这么做的。您的Foos对象由堆栈上的主程序创建,然后在库中使用。这个物体包含一个地图作为它的一部分..。

在编译主程序时,它会查看头文件等,以确定要为Foos对象分配多少堆栈空间。调用库中定义的构造函数..。可能期望对象的布局/大小完全不同。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19981921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档