什么是在c ++中为每个平台定义函数的首选方法

时间:2012-04-03 13:19:11

标签: c++ cross-platform

在头文件中我定义了以下函数

#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

是否有更优雅的方式来做到这一点(被认为是好的风格)。

2 个答案:

答案 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