当包含Windows.h导致错误A不是B的成员 [英] When include Windows.h causes the error A is not a member of B

查看:144
本文介绍了当包含Windows.h导致错误A不是B的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是我的包含文件:

The following code are my include files:

但是,我发现当我使用 #include< Windows.h> 时,项目无法编译,会出现错误:

However, I find that when I use #include <Windows.h>, the project can not compile, it will come with an error:

"LoadImageA": is not a member of "ImageData"

在这一行:

im.LoadImage("bg.png");

但是,如果我不使用#include`,一切正常。任何人都可以帮助我吗?

However, if I do not use #include `, everything works fine. Can any one help me?

推荐答案

这是Win32 API的常见问题,会影响任何具有相同名称的符号作为支持 TCHAR 数据的Win32 API函数。

This is a common problem with the Win32 API, and affects any symbols that have the same name as Win32 API functions that support TCHAR data.

在这种情况下, Windows.h 包含 winuser.h ,它定义了Win32 API LoadImage()函数,如下所示:

In this case, Windows.h includes winuser.h, which defines the Win32 API LoadImage() function as follows:

WINUSERAPI
HANDLE
WINAPI
LoadImageA(
    __in_opt HINSTANCE hInst,
    __in LPCSTR name,
    __in UINT type,
    __in int cx,
    __in int cy,
    __in UINT fuLoad);
WINUSERAPI
HANDLE
WINAPI
LoadImageW(
    __in_opt HINSTANCE hInst,
    __in LPCWSTR name,
    __in UINT type,
    __in int cx,
    __in int cy,
    __in UINT fuLoad);
#ifdef UNICODE
#define LoadImage  LoadImageW
#else
#define LoadImage  LoadImageA
#endif // !UNICODE

#define 语句是造成问题的原因。 #define 在范围内是全局的,并不尊重文件边界,名称空间,类定义等。它只是一个直接的文本替换。所以,当你的代码调用它时:

The #define statements are what is causing your problem. A #define is global in scope, and doesn't respect file boundaries, namespaces, class definitions, etc. It is just a straight text replacement. So, while your code is calling this:

im.LoadImage("bg.png");

预处理器将其更改为以下内容,这是编译器看到的内容:

The preprocessor changes it to the following, which is what the compiler sees:

im.LoadImageA("bg.png");

或者:

im.LoadImageW("bg.png");

取决于您是为MBCS还是Unicode编译项目(在这种情况下,您使用的是MBCS) )。

Depending on whether you are compiling your project for MBCS or Unicode (in this case, you are using MBCS).

如果微软对C ++开发人员更好,Win32 API头文件将使用内联函数而不是C宏,例如:

If Microsoft would be nicer to C++ developers, the Win32 API headers would use inline functions instead of C macros, eg:

WINUSERAPI
HANDLE
WINAPI
LoadImageA(
    __in_opt HINSTANCE hInst,
    __in LPCSTR name,
    __in UINT type,
    __in int cx,
    __in int cy,
    __in UINT fuLoad);
WINUSERAPI
HANDLE
WINAPI
LoadImageW(
    __in_opt HINSTANCE hInst,
    __in LPCWSTR name,
    __in UINT type,
    __in int cx,
    __in int cy,
    __in UINT fuLoad);

#ifdef __cplusplus
inline HANDLE LoadImage(
    __in_opt HINSTANCE hInst,
    __in LPCTSTR name,
    __in UINT type,
    __in int cx,
    __in int cy,
    __in UINT fuLoad)
{
  #ifdef UNICODE
  return LoadImageW(hInst, name, type, cx, cy, fuLoad);
  #else
  return LoadImageA(hInst, name, type, cx, cy, fuLoad);
  #endif // !UNICODE
}
#else
  #ifdef UNICODE
  #define LoadImage  LoadImageW
  #else
  #define LoadImage  LoadImageA
  #endif // !UNICODE
#endif // !C++

那个允许适当的范围和重载跨库,类等重复的任何名称。但是,唉,微软似乎不愿意这么多年后这样做:( Win32 API主要是为C和其他C兼容的语言设计的,它提供了非常好的对C ++的一些规定(不包括GDI +,COM等)。

That would allow proper scoping and overloading of any names repeated across libraries, classes, etc. But alas, Microsoft seems unwilling to do that after all these years :( The Win32 API is primarily designed for C and other C-compatible languages, it provides very little provisions for C++ (not counting things like GDI+, COM, etc).

在任何情况下,对于您的情况,最简单的解决方案是:

In any case, for your situation, the simplest solution is to either:


  1. ImageData.LoadImage()方法重命名为更独特的名称。

  1. rename the ImageData.LoadImage() method to a more unique name.

使用 #undef LoadImage 语句(假设您不需要使用实际的Win32 API LoadImage()函数源文件中的任何其他位置):

use an #undef LoadImage statement (assuming you don't need to use the actual Win32 API LoadImage() function anywhere else in your source file):

#undef LoadImage
im.LoadImage("bg.png");

或者,如果你想要更具限制性:

Or, if you want to be a little more restrictive:

#ifdef _WINUSER_
#undef LoadImage
#endif

im.LoadImage("bg.png");


这篇关于当包含Windows.h导致错误A不是B的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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