使用自定义工具集获取动态Atexit析构函数链接错误-eh矢量析构函数 [英] Getting dynamic atexit destructor link error with custom toolset - eh vector destructor
问题描述
尝试使用Visual Studio 2015工具集针对VS2005 CRT进行编译时,出现奇怪的链接器错误.
相同的代码可以在任何其他工具集版本(2005、2010、2012、2013)上完美编译.
该代码必须在VS2005 CRT下编译才能正确链接到其他项目.
I'm getting a weird linker error when trying to compile against a VS2005 CRT with a Visual Studio 2015 toolset.
The same code compiles perfect on any other toolset version (2005,2010,2012,2013).
The code must compile under VS2005 CRT to properly link with other projects.
如何复制:创建一个新的空动态库(dll)项目(在VS2015中,工具集v140),添加一个源(.cpp)文件:
How to reproduce: Create a new empty Dynamic Library (dll) project (In VS2015, toolset v140), add a source (.cpp) file:
//1.cpp
#include <string>
static std::wstring thisWillFail[] = { L"test" };
将VC ++包含目录和库目录更改为:
Change the VC++ include directories and Library directories to:
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\include
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\lib
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\lib
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\Lib
然后编译,您将收到此错误:
Then just compile, an you will get this error:
1>StdAfx.obj : error LNK2019: unresolved external symbol "void __stdcall `eh vector destructor iterator'(void *,unsigned int,unsigned int,void (__thiscall*)(void *))" (??_M@YGXPAXIIP6EX0@Z@Z) referenced in function "void __cdecl `dynamic atexit destructor for 'fasdfp''(void)" (??__Ffasdfp@@YAXXZ)
如果您设置库并包含VS2010 CRT和Windows SDK的路径,也会发生同样的情况.
Same will happen if you set the library and include paths to the VS2010 CRT and Windows SDK.
那么,为什么VS2015会产生这个额外的功能?最重要的是,我该如何解决呢?
我拥有的每个静态成员上都会出现相同的链接器错误,几个类中也会出现类似的链接器错误.
So, why is VS2015 generating this extra function? And most importantly how can i work around this?
The same linker error appears on every static member i have, and a similar one for several classes.
推荐答案
在VS2015中,有一个主要的此处所述,一种简单的解决方案是只是添加实际的实现.
In VS2015 there was a major refactoring in the CRT.
Part of that was changing the implementation, and the signature of __ehvec_dtor
.
As mentioned here, a simple solution would be to just add the actual implementation.
最简单的方法是将此代码添加到头文件中,并将其包含在stdafx.h中:
Simplest way is to add this code to a header file and include it in the stdafx.h:
#if defined __cplusplus_cli
#define CALEETYPE __clrcall
#else
#define CALEETYPE __stdcall
#endif
#define __RELIABILITY_CONTRACT
#define SECURITYCRITICAL_ATTRIBUTE
#define ASSERT_UNMANAGED_CODE_ATTRIBUTE
#if defined __cplusplus_cli
#define CALLTYPE __clrcall
#elif defined _M_IX86
#define CALLTYPE __thiscall
#else
#define CALLTYPE __stdcall
#endif
__RELIABILITY_CONTRACT
void CALEETYPE __ArrayUnwind(
void* ptr, // Pointer to array to destruct
size_t size, // Size of each element (including padding)
int count, // Number of elements in the array
void(CALLTYPE *pDtor)(void*) // The destructor to call
);
__RELIABILITY_CONTRACT
inline void CALEETYPE __ehvec_ctor(
void* ptr, // Pointer to array to destruct
size_t size, // Size of each element (including padding)
// int count, // Number of elements in the array
size_t count, // Number of elements in the array
void(CALLTYPE *pCtor)(void*), // Constructor to call
void(CALLTYPE *pDtor)(void*) // Destructor to call should exception be thrown
) {
size_t i = 0; // Count of elements constructed
int success = 0;
__try
{
// Construct the elements of the array
for (; i < count; i++)
{
(*pCtor)(ptr);
ptr = (char*)ptr + size;
}
success = 1;
}
__finally
{
if (!success)
__ArrayUnwind(ptr, size, (int)i, pDtor);
}
}
__RELIABILITY_CONTRACT
SECURITYCRITICAL_ATTRIBUTE
inline void CALEETYPE __ehvec_dtor(
void* ptr, // Pointer to array to destruct
size_t size, // Size of each element (including padding)
// int count, // Number of elements in the array
size_t count, // Number of elements in the array
void(CALLTYPE *pDtor)(void*) // The destructor to call
) {
_Analysis_assume_(count > 0);
int success = 0;
// Advance pointer past end of array
ptr = (char*)ptr + size*count;
__try
{
// Destruct elements
while (count-- > 0)
{
ptr = (char*)ptr - size;
(*pDtor)(ptr);
}
success = 1;
}
__finally
{
if (!success)
__ArrayUnwind(ptr, size, (int)count, pDtor);
}
}
这篇关于使用自定义工具集获取动态Atexit析构函数链接错误-eh矢量析构函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!