使用自定义工具集获取动态Atexit析构函数链接错误-eh矢量析构函数 [英] Getting dynamic atexit destructor link error with custom toolset - eh vector destructor

查看:106
本文介绍了使用自定义工具集获取动态Atexit析构函数链接错误-eh矢量析构函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆