3

我正在编译我使用的一个项目,这次使用 VS2010,只是为了发现 windows.h 中的一个包含有一个 typedef INPUT,它与我已经拥有的代码中的导出 const 字符串发生冲突。

//winuser.h(行:5332)

typedef struct tagINPUT {
    DWORD   type;

    union
    {
        MOUSEINPUT      mi;
        KEYBDINPUT      ki;
        HARDWAREINPUT   hi;
    };
} INPUT, *PINPUT, FAR* LPINPUT;

//foo.h

//stuff here
extern FOO_DLL_API const string INPUT;

现在,我不在有问题的 .cpp 中使用 INPUT(并且我不拥有大部分代码),并试图将影响降到最低,我做了以下事情:

//我的文件.cpp

#include <foo.h>
namespace windowsLib {    //I added this
#  include <windows.h>
}

using namespace windowsLib;

到目前为止,这种方法运行良好,但我想问您是否发现这种方法存在潜在问题,或者您是否有更好的建议。

编辑:

我感谢所有关于为什么这是一个坏主意的评论和解释。我从您的评论中得到的是我应该更改 foo.h 并将内容放入命名空间。但是,这样做会影响几十个文件,甚至更多,现在需要命名空间限定。

有没有办法在不触及所有这些文件的情况下做到这一点“正确的方式”?

如果我是代码的所有者,我会进行此更改并完成它,但我必须提出一个解决方案并获得批准并将其分配给某人等。因此,如果更改很小,它会更容易。

编辑2:

我的最终建议是将班级分成两部分,如下所示:

//存根.cpp

#include <windows.h>

//Implementation of wrapper methods

//存根.h

class stub {
    //public wrapper methods
}

//我的文件.cpp

#include <stub.h>
#include <foo.h>    

我接受 Benlitz 的回答,因为该建议还可以解决我目前面临的当前最小影响约束的问题。不过,我感谢大家的意见。

4

4 回答 4

3

不仅语言不允许这样做(假设标准头文件将包含在命名空间中),而且还存在调用在中声明的任何函数<windows.h>并发现链接器将在命名空间中查找它们的问题windowsLib

就是不行!

于 2012-05-15T20:02:34.173 回答
2

至少这似乎是个坏主意。

1)如果这实际上是您的代码,那么添加命名空间没有任何好处,因为您using namespace windowsLib;在下一行。不会INPUT有歧义吧?

2)您可能包含其他使用来自的东西windows.h并且不会使用正确符号的标题。想象一下,包含一个定义返回函数的头文件INPUT。这将如何解决?

我建议您谨慎行事,只需重命名您的类型。

于 2012-05-15T19:58:31.153 回答
1

正如其他答案中所解释的那样,这是一个坏主意。这是一个可以帮助您解决问题的想法:

//我的文件.cpp

#define INPUT UnusedSymbol
#include "foo.h"
#undef INPUT

#include "windows.h"

这可能有效,因为 INPUT 是 foo.h 中的外部变量,因此只要您不在 myfile.cpp 中使用它,编译器和链接器都不会关心它。UnusedSymbol 是一个虚拟名称,您可以编写源代码中未使用的任何名称。

于 2012-05-15T20:12:38.880 回答
1

在 windows.h 周围放置一个命名空间对我来说听起来很危险。它可能会隐藏你需要的东西。除非您在下一行中导入命名空间。

我宁愿将命名空间放在 foo.h 周围:

namespace fooLib {
#include "foo.h"
}

using fooLib;

我想这只是将问题从操作系统代码转移到 foo 代码,但这对我来说似乎更安全。

另一种方法可能是围绕 foo 构建一个包装器,该包装器调用 foo 函数并在单独的小包装器库中返回 foo 全局变量。一个不需要 windows.h 的。您可以将此包装器放入名称空间中以防止再次发生这种情况。

我在这里假设您没有能力在 foo.h 中重命名事物foo.h或将fooLib命名空间放在 foo.h 中的事物周围。

如果您可以触摸foo.h,最好在 foo.h 中重命名 INPUT 或将 foo.h 内容放在自己的名称空间中。我认为fooLib命名空间会有很大(明显)的好处。

于 2012-05-15T20:16:29.727 回答