【发布时间】:2018-11-16 02:02:16
【问题描述】:
编辑:我发现了一个类似的问题,答案基本上是 windows.h 不好,您必须重命名函数或 #undef 宏:Other's library #define naming conflict
但是,由于 LoadLibrary 在调试和发布版本下的冲突行为,我相信我的仍然不同。
我正在使用 Visual Studio 在 Windows 上进行编程,但在 windows.h 使用的预处理器指令及其包含的标头中遇到了一些特殊问题。
我们的项目在自己的命名空间MyProject::FileManager::CreateFile() 中有一个函数。包含 windows.h 后,由于链接器错误指出无法解析 MyProject::FileManager::CreateFileW(请注意函数名称末尾的 W),我们的代码无法编译。这不是静态函数,它是使用 file_manager.CreateFile(...) 调用的 FileManager 对象的成员函数。
在 Visual Studio 中突出显示该函数时,工具提示会显示以下内容:
#define CreateFile CreateFileW
我们很困惑,但只是将函数重命名为一种解决方法。但是后来我们在尝试从 Windows API 中使用的 LoadLibrary 函数遇到了类似的问题。在调试模式下编译,LoadLibrary 被定义为LoadLibraryW(),它以 LPCWSTR(宽字符串)作为参数。当我尝试在发布模式下构建时,这个函数现在被定义为LoadLibraryA(),它采用普通的 LPCSTR。这破坏了我们的构建,因为代码是在 LoadLibrary 采用 LPCWSTR 的假设下编写的。
那么,我的问题是,程序员应该如何处理这个问题?我应该用#ifdef 检查调试或发布模式来包装我对LoadLibrary 的调用吗?还是有更简单的解决方案?
另外,我在 github 上发现了一个有趣的头文件,它似乎是为了 #undef'ing 所有这些函数名称而创建的:
https://github.com/waTeim/poco/blob/master/include/Poco/UnWindows.h
【问题讨论】:
-
这就是宏的危害,当你#include windows.h 时你无法真正逃避这些。无论如何,当客户端代码也包含它时,它往往会达到一个好的结局。但这很难保证。选择其他名称或使用#undef。
-
如果您收到
LoadLibraryA,请确保已定义UNICODE(参见第一个链接)或直接使用LoadLibraryW。 -
@EvilTeach -- 命名空间无济于事;这些是在 windows.h 中定义的宏,它们会感染一切。