这是 Win32 API 的常见问题,并且会影响与支持的 Win32 API 函数同名的任何符号TCHAR
data.
在这种情况下,Windows.h
包括winuser.h
,它定义了 Win32 APILoadImage()
函数如下:
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
The #define
陈述是导致您的问题的原因。 A#define
范围是全局的,不考虑文件边界、命名空间、类定义等。它只是直接的文本替换。因此,当您的代码调用此代码时:
im.LoadImage("bg.png");
预处理器将其更改为以下内容,这就是编译器所看到的:
im.LoadImageA("bg.png");
Or:
im.LoadImageW("bg.png");
取决于您是针对 MBCS 还是针对 Unicode 编译项目(在本例中,您使用的是 MBCS)。
如果 Microsoft 对 C++ 开发人员更好一点,Win32 API 标头将使用内联函数而不是 C 宏,例如:
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 等)。
无论如何,根据您的情况,最简单的解决方案是:
重命名ImageData.LoadImage()
方法给一个更独特的名字。
-
use an #undef LoadImage
声明(假设您不需要使用实际的 Win32 APILoadImage()
在源文件中的其他位置运行):
#undef LoadImage
im.LoadImage("bg.png");
或者,如果您想限制更多一些:
#ifdef _WINUSER_
#undef LoadImage
#endif
im.LoadImage("bg.png");