1

我想让我的程序的源代码跨平台,到目前为止一切都很好。我有几个函数,它们只是语法上的不同,所以我在开始时检查一些定义,看看它是 windows 还是 linux,并根据它是哪个变量将变量设置为 1 或 0。我的想法是我可以对该变量进行 if 语句检查以跳过不正确的语法使用。我现在意识到它不会编译,因为编译器仍然“看到”有问题的代码。你能

 #ifdef

划分某些函数并在代码中调用它们?有什么建议么?

4

4 回答 4

4

您必须将整个非跨平台部分包含在#ifdefs 之间。

例如:

int gettimeofday(struct timeval *tp, void *tzp)
{
#ifdef WIN32

    struct _timeb timebuffer;

    _ftime(&timebuffer);
    tp->tv_sec = timebuffer.time;
    tp->tv_usec = timebuffer.millitm * 1000;

    return 0;

#else

    tp->tv_sec = time(NULL);
    tp->tv_usec = 0;

    return 0;

#endif
}

像这样编译器不会看到有问题的代码,因为它在预处理步骤中被删除了。

于 2013-05-18T22:53:54.753 回答
1

是的,在最简单的情况下并假设例如一个名为 foo() 的函数,您可以执行类似的操作...

/* Are we on a Windows platform ? */
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__)
void foo( ... ) {
   /* windows implementation */
}

/* Are we on a Linux platform ? */
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
void foo( ... ) {
   /* linux implementation */
}

/* Are we on a Unix platform ? */
#elif defined(__unix__) || defined(__unix) || defined(unix)         \
|| defined(__CYGWIN__) || ( defined(__APPLE__) && defined(__MACH) )
void foo( ... ) {
   /* unix implementation */
}

/* Are we on Unsupported platform? */
#else
void foo( ... ) {
   /* generic implementation */
}
#endif

另一种选择是为每个操作系统设置不同的头文件,以实现不同版本的功能,然后有条件#include地使用适当的头文件。

假设一些名为:myproj_win32.h、myproj_linux.h、myproj_unix.h、myproj_generic.h 的头文件你可以做这样的事情......

/* Are we on a Windows platform ? */
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__)
#include "myproj_win32.h"

/* Are we on a Linux platform ? */
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
#include "myproj_linux.h"

/* Are we on a Unix platform ? */
#elif defined(__unix__) || defined(__unix) || defined(unix)         \
|| defined(__CYGWIN__) || ( defined(__APPLE__) && defined(__MACH) )
#include "myproj_unix.h"
}

/* Are we on Unsupported platform? */
#else
#include "myproj_generic.h"
#endif

只有正确版本的实现才会被编译。还有更多选择,但这些应该可以帮助您入门。

编辑

这是一个有用的链接,其中包含用于常见 C/C++ 编译器的预定义宏。

于 2013-05-18T23:06:55.710 回答
1

当然可以,这几乎是标准的做法,至少对于一小部分代码来说是这样。对于更大的块,您可能希望使用构建系统,并将特定于平台的代码放在单独的文件中(foo_win.c、foo_unix.c);然后,根据操作系统,您只在应用程序中编译和链接正确的应用程序。

有很多预处理器定义会告诉你操作系统、编译器、架构和其他东西;看看 Qt 如何检测操作系统编译器

于 2013-05-18T22:55:23.693 回答
1

cpp -d M < /dev/null > somefile将显示您可以从编译器获得的默认功能测试宏设置(#define 值) - 对于您要测试的宏(#ifdef)内容。你必须在每个系统上运行它,另外一些编译器默认添加宏,例如 gcc。

#ifdef _SUN_OS 
// put all Sun OS code here

#endif

您必须找到宏来识别您的所有平台。

于 2013-05-18T22:57:51.753 回答