假设你有一段代码必须根据程序运行的操作系统而不同。
这里有一个老派的做法:
#ifdef WIN32
// code for Windows systems
#else
// code for other systems
#endif
但是肯定有更为简洁的解决方案,对吧?
Sleep(DWORD milliseconds)
和sleep(uint seconds)
。如果我错了,请告诉我。 - Marc.2377sleep()
函数包装它们,使用一个公共的时间基准。例如:xsleep(xUint64_t 纳秒)
。你的所有代码都使用这个函数,并且你特定平台的 HAL 将其转换 :) 唯一有问题的时候是当你尝试使用截然不同的系统(例如:具有不同线程、安全、网络模型的系统)时。在这种情况下,编写 HAL 就变得更加困难了。 - Cloud在我的职业生涯中,我不得不做很多这样的工作,支持在嵌入式设备上构建和运行的代码,以及在Windows上运行,并在不同的ASIC和/或ASIC修订版上运行。
我倾向于按照你的建议去做,当事情真正分歧时,我会继续定义我想要在平台之间固定的接口,然后有单独的实现文件甚至库。随着代码库变老并需要添加更多的异常情况,它可能会变得非常混乱。
有时您可以将此类内容隐藏在标头文件中,使您的代码看起来“干净”,但很多时候这只是在一堆宏魔法背后模糊了视线。
我唯一要补充的是,如果没有定义任何选项,则我倾向于使#ifdef / #else / #endif链失败。这迫使我在新版本出现时重新审查问题。有些人喜欢设置默认值,但我发现这只会隐藏潜在的失败。
当然,我正在嵌入式世界工作,其中代码空间至关重要(因为内存很小且固定),而代码清洁度不幸必须退居次要地位。
对于非平凡项目的一种被采用的做法是将特定于平台的代码写在单独的文件中(如果适用,还要写在单独的目录中),尽可能避免“本地化”的 #ifdef
。
比如你正在开发一个名为“Example”的库,example.hpp
将是你的库头文件:
example.hpp
#include "platform.hpp"
//
// here: platform-independent declarations, includes etc
//
// below: platform-specific includes
#if defined(WINDOWS)
#include "windows\win32_specific_code.hpp"
// other win32 headers
#elif defined(POSIX)
#include "posix/linux_specific_code.hpp"
// other linux headers
#endif
platform.hpp(简体)
#if defined(WIN32) && !defined(UNIX)
#define WINDOWS
#elif defined(UNIX) && !defined(WIN32)
#define POSIX
#endif
win32_specific_code.hpp
void Function1();
win32_specific_code.cpp
#include "../platform.hpp"
#ifdef WINDOWS // We should not violate the One Definition Rule
#include "win32_specific_code.hpp"
#include <iostream>
void Function1()
{
std::cout << "You are on WINDOWS" << std::endl;
}
//...
#endif /* WINDOWS */
当然,在您的 linux_specific_code.hpp
文件中也要声明 Function1()
。
然后,在为 Linux 实现它时(在 linux_specific_code.cpp
文件中),一定要像我上面做的那样,将所有内容都包围在条件编译中(例如使用 #ifdef POSIX
)。否则,编译器将生成多个定义,并且会出现链接错误。
现在,您的库的用户所需做的就是在他的代码中添加 #include <example.hpp>
,并在编译器的预处理器定义中放置 #define WINDOWS
或 #define POSIX
。实际上,第二步可能根本不必要,假设他的环境已经定义了 WIN32
或 UNIX
宏之一。这样,Function1()
就可以以跨平台的方式从代码中使用了。
这种方法基本上是Boost C++ Libraries所使用的方法。我个人认为它很干净、合理。然而,如果你不喜欢它,你可以阅读Chromium's conventions for multi-platform development,了解一种略有不同的策略。
__int64
的头文件。 - Baum mit Augen