Getting dynamic error of link to destructor using a special set of tools - eh vector destructor

I get a strange linker error when trying to compile using VS2005 CRT using the Visual Studio 2015 toolkit.
The same code compiles fine in any other version of the toolbox (2005,2010,2012,2013).
The code must be compiled under VS2005 CRT for proper communication with other projects.

How to reproduce: Create a new empty Dynamic Library (dll) project (in VS2015, toolset v140) add a source file (.cpp):

//1.cpp #include <string> static std::wstring thisWillFail[] = { L"test" }; 

Change the VC ++ inclusion 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, 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) 

The same thing happens if you install the library and include the paths to VS2010 CRT and the Windows SDK.

So why is VS2015 generating this extra feature? And most importantly, how can I get around this?
The same linker error appears on every static member that I have, and similar for several classes.

0
source share
1 answer

In VS2015, there was a major refactoring in CRT .
This partly changed the implementation and signature of __ehvec_dtor .
As mentioned here , a simple solution would be to simply add the actual implementation.

The easiest way is to add this code to the header file and include it in 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); } } 
0
source

Source: https://habr.com/ru/post/1269332/


All Articles