将C程序链接到C ++共享库

时间:2014-07-17 14:30:05

标签: c++ c boost shared-memory

我有用C ++编写的共享库,它为用C ++编写的不同应用程序提供了一些API调用,现在我想在C程序中使用这个库。原始库包含的数据类型只对C ++有效,如std :: string和std :: vector,如下所示:

typedef u_int32_t           ApplicationID;
typedef std::string         IPAddress;
typedef std::vector<int>    SDLIST;

这些数据类型被用作API的输入参数:

register_client(IPAddress ip);
export(ApplicationID id, SDLIST *list);

但是在C中,我们没有字符串和向量,这两种数据类型应该修改如下:

typedef char*   IPAddress;
typedef int*    SDLIST;

我尝试在代码中进行以下更改:

typedef u_int32_t           ApplicationID;
enter code here
#ifdef __cplusplus
    typedef std::string         IPAddress;
    typedef std::vector<int>    SDLIST;
#else
    typedef char*               IPAddress;
    typedef int*                SDLIST;
#endif


#ifdef __cplusplus
extern "C" {
#endif

    register_client(IPAddress ip);
    export(ApplicationID id, SDLIST *list);

#ifdef __cplusplus
}
#endif

我的问题是:

  1. 这是构建可在C&amp; C中使用的库的正确方法吗? C ++?

  2. 我的共享库使用Boost Interprocess库,它是标准POSIX共享内存调用的包装器。每当我尝试将此共享库链接到任何应用程序时,我都应该在应用程序中再次包含lrt。所以我的问题是可以将共享库静态链接到lrt库,而无需在使用我的共享库的所有应用程序中包含lrt吗?

2 个答案:

答案 0 :(得分:3)

如果您希望这项工作,您将需要构建一个C ++接口库,该库实现基于C的API,将C数据类型转换为C ++数据类型。特别是std :: string不是char *而vector不是int *。

例如,如果API定义了像

这样的C ++函数
bool CPPAPIFunction( std::string str, std::vector<int> vec )

你需要实现一个包装函数(编译和链接为C ++),如

int myCMappingFunction( char *cstr, int *carray, int arraylen )
{
    std::string str( cstr );
    std::vector<int> vec;
    for (int i =0; i < arraylen; i++ )  // ... copy C array into C++ vector
    return (int)CPPFAPIFunction( str, vec );
}

另外不要忘记在extern“C”块中声明你的包装函数,这样名称修改将是C风格而不是C ++。

答案 1 :(得分:1)

让我逐一回答你的问题:

  1. 显然,根据您的用例,您希望混合使用哪种代码。如果要提供可以从C和C ++调用库的功能,则库接口应该与C兼容。查看Using C++ library in C code,了解如何在C接口中包装C ++函数。

  2. 通常建议您不要使用所有依赖项打包库,因为它会产生大量二进制文件并且会破坏共享库的用途,除非您打包的依赖项很小。但是,在您的情况下,如果您想这样做,则需要创建静态共享库。但是,无法从两个共享库创建。您需要两者的目标文件。请参阅Merge multiple .so shared libraries获取答案。