在头文件中我定义了以下函数
#ifndef OS_H
#define OS_H
#include <string>
#include <vector>
int GetDirectoryFiles(std::string directory, std::vector<std::string> &files);
#endif /* OS_H */
我希望每个平台都有单独的实现
#include "os.h"
#include <iostream>
#ifdef OSWIN
#include <windows.h>
#elif OSLINUX
#include <dirent.h>
#endif
int GetDirectoryFiles(std::string directory, std::vector<std::string> &files)
#ifdef OSLINUX
{
DIR *dp;
struct dirent *dirp;
if((dp = opendir(dir.c_str())) == NULL) {
cout << "Error(" << errno << ") opening " << dir << endl;
return errno;
}
while ((dirp = readdir(dp)) != NULL) {
files.push_back(string(dirp->d_name));
}
closedir(dp);
return 0;
}
#elif OSWIN
{
std::clog << "entered!" << std::endl;
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(directory.c_str(), &FindFileData);
if ( hFind == INVALID_HANDLE_VALUE )
return -1;
do {
files.push_back(FindFileData.cFileName);
} while(FindNextFile(hFind, &FindFileData) != 0);
FindClose( hFind );
return 0;
}
#endif
是否有更优雅的方式来做到这一点(被认为是好的风格)。
答案 0 :(得分:5)
处理此问题的典型方法是在共享头文件中包含函数声明,然后每个平台有一个cpp文件,其中包含此函数的不同平台特定定义。然后,您的构建系统仅在相应的特定于平台的cpp文件中创建并链接。
即
Filesystem.h
#include <string>
#include <vector>
int GetDirectoryFiles(std::string directory, std::vector<std::string> &files);
Filesystem_Windows.cpp:
#include "Filesystem.h"
int GetDirectoryFiles(std::string directory, std::vector<std::string> &files);
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(directory.c_str(), &FindFileData);
...
return 0;
}
Filesystem_Linux.cpp:
#include "Filesystem.h"
int GetDirectoryFiles(std::string directory, std::vector<std::string> &files);
{
DIR *dp;
struct dirent *dirp;
...
return 0;
}
参见Qt的源代码树,这是一个非常流行的跨平台C ++库,作为这种结构的一个例子。
答案 1 :(得分:3)
我会在除了几个点之外的两个平台的代码几乎相同的情况下使用#ifdef。例如,如果你有一个需要clock()/ GetTickCount()的函数,但是否则是相同的。
对于完全不同(或不同)的模块,如您给出的示例,我在/ src目录中有子目录,一个/ src / common用于独立于平台,然后一个用于每个平台(/ src / win,/ src / linux等)我在每个平台使用完全相同的模块名称,在makefile中我有条件来定义一个$ native宏作为/ src / win或其他根据我在哪里编译。然后,模块列表中的每个特定于平台的源名称都定义为$ native / [name] .cpp