包括具有一个头文件和单独源文件的特定于平台的库

时间:2012-07-16 14:18:03

标签: c++ static-linking

我正在编写一个独立于平台的套接字库。基本文件结构如下:

source directory
|_________________________
|            |            |
v            v            v    
header.hpp   win32        linux
             |            |
             v            v
             source.cpp   source.cpp

头文件包含在操作系统中通用的任何#include。源文件#include平台特定库。

我已经构建了许多像这样的项目,但是我遇到了套接字问题。因为我正在为我的函数参数指定默认值,header.h需要头文件中使用的#defines平台特定库,例如SOCK_STREAMAF_INET和{{ 1}}。

现在,我不想在我的头文件中使用SOMAXCONN语句,因为我希望所有特定于平台的代码都位于不同文件夹中的源文件中。

我基本上被困在一块岩石和一块坚硬的地方之间?是否避免使用#ifdef _WIN32并指定与标头相关的#ifdef #includes互斥的默认参数值?

3 个答案:

答案 0 :(得分:2)

您可以使用通常无效的其他默认值。然后,您的平台特定代码可以检测此特殊默认值,并将该值替换为您实际希望它表示的值。

/* header */
int mysocket (int domain = -1, int type = -1, int protocol = 0);

/* implementation */
int mysocket (int domain, int type, int protocol) {
    if (domain == -1) domain = AF_INET;
    if (type == -1) type = SOCK_STREAM;
    // ...wrapper specific stuff for the platform...
    return ::socket(d, t, p);
}

另一种可能性是让原型中缺少参数。

/* header */
int mysocket ();
int mysocket (int domain);
int mysocket (int domain, int type);
int mysocket (int domain, int type, int protocol);

/* implementation */
int mysocket () { return mysocket(AF_INET, SOCK_STREAM, 0); }
int mysocket (int d) { retrun mysocket(d, SOCK_STREAM, 0); }
int mysocket (int d, int t) { return mysocket(d, t, 0); }
int mysocket (int d, int t, int p) {
    // ...wrapper specific stuff for the platform...
    return ::socket(d, t, p);
}

答案 1 :(得分:2)

您可以通过在平台独立标头中声明并在平台特定.cpp文件中正确定义的函数检索它们来获取默认参数。

或者,您也可以在平台独立标头中将它们声明为extern consts,并在您的平台特定.cpp中适当地定义它们。

答案 2 :(得分:1)

在库中添加一个抽象层,并将其转换为平台本机类型。

namespace MySocketLibrary
{
    enum SocketType
    {
        StreamSocket,
        DataGramSocket,
        RawSocket,
        // etc.
    }
}

对于我的平台特定Win32实施,然后:

int translate_socket_type(const MySocketLibrary::SocketType socket)
{
    switch(socket)
    {
        case  MySocketLibrary::StreamSocket:
            return 1;
        // etc.
    }
}

很多库(如boost::asio)都这样做。