我想问一下是否可以在头文件中使用#ifdef块中定义的实体。为了清楚起见,我有以下代码:
#ifdef WIN32
#include <winsock2.h>
#define SOCKET_HANDLE SOCKET
#define CONNECTION_HANDLE SOCKET
#endif
SOCKET_HANDLE createServerSocket(const char* hostAddress, short port);
我是Java开发人员,这对我来说似乎完全没问题。但编译器存在此问题。
你能解释为什么这段代码有问题吗? 另外我怎么强制编译它。 (我们的想法是在编译时根据运行平台确定通用接口和条件编译来确定实际类型。)
由于
答案 0 :(得分:3)
#ifdef
后缺少令牌。在这种情况下,它看起来像你想为Windows构建:
#ifdef WIN32
在其他平台上进行编译时,您可能需要#else
分支。例如:
#ifdef WIN32
#include <winsock2.h>
#define SOCKET_HANDLE SOCKET
#define CONNECTION_HANDLE SOCKET
#else
#define SOCKET_HANDLE int
#define CONNECTION_HANDLE int
#endif
答案 1 :(得分:1)
#ifdef SOMETHING
代码中缺少SOMETHING
在这里阅读预处理指令
http://msdn.microsoft.com/en-us/library/3sxhs2ty(v=vs.80).aspx
编辑:编辑问题后,我在Dev Cpp中尝试了这个。它正常工作,因为WIN32
是为我定义的。甚至我的IDE中定义了_WIN32
。两者都运作良好
答案 2 :(得分:1)
#ifdef
是一个条件预处理器语句。与if
语句非常相似,它们需要进行一些评估,因此可以采用一个或另一个分支。
在#ifdef
的情况下,它正在评估是否定义了给定的宏。 e.g。
#ifdef BLAH
/* true branch */
#else
/* false branch */
#endif
检查是否定义了BLAH宏。根据结果,包含并编译了真或假分支中的代码,其他代码被丢弃。
在您的特定情况下,#ifdef
的使用非常清楚,以确保使用适合于编译代码的操作系统的头和套接字类型(忽略交叉编译的时刻)。
对于问题中的代码,您要检查宏_WIN32
和/或_WIN64
。这些是针对Windows操作系统的大多数编译器隐式定义的。请注意,在VC ++ _WIN32
中定义了32位和64位Windows,而_WIN64
仅定义为64位Windows。有关详细信息,请参阅this discussion。
注意到您对问题的更改以及您在评论中发布的确切错误消息后,问题就出现了问题:
WIN32
是错误的宏。它应该是_WIN32
或_WIN64
。见上文。#define
和#include
,因此SOCKET_HANDLE
和CONNECTION_HANDLE
都未定义。 SOCKET_HANDLE createServerSocket(const char* hostAddress, short port);
时,它无法识别SOCKET_HANDLE
并退出并显示错误解决方案是修复您正在检查的宏,将其从WIN32
更改为_WIN32
或_WIN64
。此外,您应该在操作系统检测完全失败的情况下提供#else
分支,例如假设您正在$mostlikelyos
以及#define
和#include
进行适当的编译。