在开发中,如何将代码做到跨平台,如何保持 C/C++ 代码能够在多个平台上编译,是一个值得研究的问题。
此外,不同平台对某些操作有自己独特的优化,例如FFT(快速傅里叶变化)在 android 和 ios 上都有自己的独特的优化方式,如何在特定平台做优化,同样值得研究
混乱的 #ifdef
如何编写跨平台的代码呢?哥们,你脑袋里蹦出的第一个想法应该是使用:#ifdef
因此,你写的跨平台代码类似这样:
头文件:
void print_something();
源文件:
#include "a.h"
#ifdef _WIN32_
void print_something()
{
printf("_WIN32_");
}
#ifdef _LINUX_
void print_something()
{
printf("_LINUX_");
}
#ifdef _IOS_
void print_something()
{
printf("_IOS_");
}
#ifdef _ANDROID_
void print_something()
{
printf("_ANDROID_");
}
#endif
也许有成百上千处的代码充斥着这样一堆的#ifdef
,说实话,自打我第一次看见这种实现方式时就觉得它不够优雅,它很混乱。
只编译特定平台的代码
更加优雅的方式就是:只编译特定平台的代码
利用 cmake 这样的工具,在 CMakeLists.txt 中,你知道你关心哪个平台,所以你可以只编译特定平台的. c/.cpp 文件,构建项目并忽略其他平台的代码。当你阅读代码的时候,就不用再看到一段的#ifdef
了,因为他们被分成了不同的文件,这些文件永远都不会在同一个版本中冲突
因此,我可以构建一个头文件 a.h 和四个不同的. cpp 文件:a_win.cpp, a_linux.cpp, a_ios.cpp 和 a_android.cpp
然后在 CMakeLists.txt 中可以这么写:
if(WIN32)
FILE(GLOB PLATFORM_SOURCES *_win.cpp)
elseif(LINUX)
FILE(GLOB PLATFORM_SOURCES *_linux.cpp)
elseif(IOS)
FILE(GLOB PLATFORM_SOURCES *_ios.cpp)
elseif(ANDROID)
FILE(GLOB PLATFORM_SOURCES *_android.cpp)
endif()
add_library(a_lib ${PLATFORM_SOURCES})
这么做阅读和调整代码都非常简单,因为与平台相关的代码都单独放在一个文件中,比起原来丑陋的代码清晰了很多
Q&A
Q: 只有少量的跨平台代码也要用这种方式吗?
A: 不,如果只有少量的 #ifdef 并且不破坏代码的整洁,完全是可以接受的。因为我们的目的就是保持跨平台代码的整洁。