我正在编译我使用的一个项目,这次使用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(我没有拥有大部分代码),并且试图将影响降到最低,我做了以下事情:
// MYFILE.CPP
#include <foo.h>
namespace windowsLib { //I added this
# include <windows.h>
}
using namespace windowsLib;
到目前为止,这种方法运行良好,但我想问你是否看到这种方法的潜在问题,或者你有更好的建议。
修改
我感谢所有关于为什么这是一个坏主意的评论和解释。我从你的评论中得到的是我应该改变foo.h并将内容放入命名空间。但是,通过这样做,我会影响几十个文件,还有一些,现在需要命名空间资格。
有没有办法以“正确的方式”执行此操作而不触及所有这些文件?
如果我是代码的所有者,我会做这个改变并完成它,但我必须提出一个解决方案,并将其批准并分配给某人等。所以如果更改是更容易的话最小的。
编辑2:
我的最终建议是将课程分成两部分,如下所示:
// stub.cpp
#include <windows.h>
//Implementation of wrapper methods
// stub.h
class stub {
//public wrapper methods
}
// MYFILE.CPP
#include <stub.h>
#include <foo.h>
我接受Benlitz的回答,因为这个建议也可以解决我目前面临的当前最小影响限制的问题。不过,谢谢大家的意见。
答案 0 :(得分:3)
不仅语言不允许(假设标准头将包含在命名空间中),还存在调用在<windows.h>
中声明的任何函数并发现该问题的问题链接器将在命名空间windowsLib
中查找它们。
只是不起作用!
答案 1 :(得分:2)
至少这似乎是一个坏主意。
1)如果这实际上是您的代码,添加命名空间没有任何好处,因为您在下一行有using namespace windowsLib;
。无论如何,INPUT
不会有歧义吗?
2)您可能包含使用来自windows.h
的内容的其他标头,并且不会使用正确的符号。想象一下,包括一个标题,它定义了一个返回INPUT
的函数。怎么会有效?
我建议你安全地播放,只需重命名你的类型。
答案 2 :(得分:1)
如其他答案中所解释的那样,这是一个坏主意。以下是一个可以帮助您解决问题的想法:
// MYFILE.CPP
#define INPUT UnusedSymbol
#include "foo.h"
#undef INPUT
#include "windows.h"
这可能有效,因为INPUT是foo.h中的一个外部变量,所以只要你不在myfile.cpp中使用它,编译器和链接器都不会关心它。 UnusedSymbol是一个虚拟名称,您可以编写源中未使用的任何名称。
答案 3 :(得分:1)
在windows.h周围放置命名空间听起来很危险。它可能会隐藏你需要的东西。除了你在下一行导入命名空间之外。
我会尽快将名称空间放在foo.h:
namespace fooLib {
#include "foo.h"
}
using fooLib;
我想这只是将问题从操作系统代码转移到foo代码,但这对我来说似乎更安全。
另一种方法可能是在foo周围构建一个包装器,它调用foo函数并在一个单独的小包装器库中返回foo globals。一个不需要windows.h。您可以将此包装器放在命名空间中以防止再次发生这种情况。
我假设您不能够重命名foo.h
中的内容或将fooLib
命名空间放在foo.h中的内容中。
如果您可以触摸foo.h
,最好在foo.h中重命名INPUT或将foo.h内容放在自己的命名空间中。我认为fooLib
命名空间会带来很大的(明显的)好处。