相关文章推荐
帅气的酱牛肉  ·  LDAP和Active ...·  3 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am currently updating an ancient program which was last compiled with visual studio 2008. I am updating it (.lib project) to visual studio 2017 for the newest windows sdk (10.0.15063.0), however, the gdiplus library throws an ambiguous symbol error. More specifically:

3>c:\program files (x86)\windows kits\10\include\10.0.15063.0\um\GdiplusPath.h(145): error C2872: 'byte': ambiguous symbol
3>c:\program files (x86)\windows kits\10\include\10.0.15063.0\shared\rpcndr.h(191): note: could be 'unsigned char byte'
3>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\include\cstddef(15): note: or 'std::byte'

The standard attempts that I have found at this issue unfortunately suppose that the ambiguity error is made by me directly, and not by a new inclusion by visual studio (Which is what I understand cstddef to be?).

So how can I point an external library towards using one symbol definition or the other?

Any help is greatly appreciated.

This problem occurs because recent standard introduced ::std::byte and ::byte types which will clash with byte type defined in rpcndr.h:

// cstddef
enum class byte : unsigned char {};
// rpcndr.h
typedef unsigned char byte;

But that is not the only problem with windows headers, they also introduce min and max macros (required by gdiplus) that clash with <limits> content.

So the workaround would be carefully control how windows and gdi plus headers are included, like this:

//  global compilation flag configuring windows sdk headers
//  preventing inclusion of min and max macros clashing with <limits>
#define NOMINMAX 1
//  override byte to prevent clashes with <cstddef>
#define byte win_byte_override
#include <Windows.h> // gdi plus requires Windows.h
// ...includes for other windows header that may use byte...
//  Define min max macros required by GDI+ headers.
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#else
#error max macro is already defined
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#else
#error min macro is already defined
#endif
#include <gdiplus.h>
//  Undefine min max macros so they won't collide with <limits> header content.
#undef min
#undef max
//  Undefine byte macros so it won't collide with <cstddef> header content.
#undef byte

Note that this approach implies that user code never uses byte, min and max from windows sdk headers.

Also byte may clash with other third-party libraries.

Thanks a lot. defining byte as BYTE from minwindef.h solved the issue. I have fortunately had control over the definitions from min and max in my own code. – Kasper Ingdahl Andkjær Aug 30, 2017 at 11:31

For Visual Studio, this behavior can be turned off by defining the preprocessor value _HAS_STD_BYTE to 0.

taken from this article.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.