在我正在使用的应用程序(使用Visual Studio 2015构建)中,我有以下结构:
Project A -> Native DLL project. This references project B
Project B -> Native static lib project. This references project C.
Project C -> Static lib project with CLR support turned on.
Project A
从Project B
调用一个函数,该函数又从Project C
创建一个类的实例。实例化的类有一个成员,它是托管对象的包装器。
我面临的问题是,当我在发布模式下构建代码时,一旦代码尝试从Project C
实例化该类,它就会爆炸并说堆已经损坏。它爆炸的地方似乎是C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\crt\src\vcruntime\pureMSILcode.cpp
[System::Diagnostics::DebuggerStepThroughAttribute]
_CRT_SECURITYCRITICAL_ATTRIBUTE
int __clrcall _initterm_e (
_PIFV * pfbegin,
_PIFV * pfend
)
{
int ret = 0;
/*
* walk the table of function pointers from the bottom up, until
* the end is encountered. Do not skip the first entry. The initial
* value of pfbegin points to the first valid entry. Do not try to
* execute what pfend points to. Only entries before pfend are valid.
*/
while ( pfbegin < pfend && ret == 0)
{
/*
* if current table entry is non-NULL, call thru it.
*/
if ( *pfbegin != NULL )
ret = (**pfbegin)();
++pfbegin;
}
return ret;
}
现在这就是......如果我将Project C
转换为DLL(而不是静态库),一切正常。更有趣的是,当我在Visual Studio 2013中构建代码时,所有这一切都工作正常。使用VS2015,如果我在调试中构建代码,我不会得到任何堆损坏,但它会爆炸在发布。
我知道在静态库中使用CLR不是最好的主意,但是我似乎无法找到有关在静态库中支持CLR的问题的任何好信息。此外,这在VS2013中运行良好。
我可以将Project C
更改为DLL(在支持CLR时更有意义),但是我想了解在转换为VS2015时导致当前设置爆炸的原因。
以下是每个项目相关代码的近似表示:
项目C:
foo.h中
class FooA
{
public:
FooA();
private:
struct FooAImpl;
std::unique_ptr<FooAImpl> _impl;
};
Foo.cpp中
struct FooA::FooAImpl
{
gcroot<ManagedFoo^> managedFoo;
FooAImpl(ManagedFoo^ managedFoo_) :
managedFoo(managedFoo_)
{
}
};
FooA::FooA()
{
_impl = std::unique_ptr<FooAImpl>(new FooAImpl(gcnew ManagedFoo()));
}
项目B:
FooB.h
class FooB
{
public:
Result GetResult();
};
FooB.cpp
Result FooB::GetResult()
{
FooA fooA;
Result r = ...;
return r;
}
项目A
FooC.h
class FooC
{
public:
void Bar();
private:
std::unique_ptr<FooB> m_pFooB;
};
FooC.cpp
void FooC::Bar()
{
Result r = m_pFooB->GetResult();
}
希望有人了解一下在拥有CLR支持的静态库时可能出现的问题。希望我提供的信息能够很好地描述问题。