2014-07-17 45 views
3

我有用C++编写的共享库,它提供了用C++编写的不同应用程序的一些API调用,现在我想在C程序中使用这个库。原始库包含数据类型仅适用于C++等的std :: string和std ::矢量如下:将C程序链接到C++共享库

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 & C++中使用的库以正确的方式?

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

+0

除非你也用C编译库,否则包含的头文件和底层定义将不匹配。相反,将接口更改为仅可C调用,或者添加一个新的头文件和函数,用于“包装”C++代码并且是可C调用的。 – crashmstr

+0

你为什么要用两种语言写它?您可以创建一个C库并为其编写C++绑定,或者编写一个C++库并为其编写C绑定。然后将该图书馆与您的应用程序连接起来,然后瞧。 – maxdev

+0

DLL的导出函数和数据类型应该使用C风格。 – Yuan

回答

3

如果你想要这个工作,你将需要建立一个实现了C的数据类型转换成C++数据类型一个C API基于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. 很显然,这是按照你想混什么样的代码你的使用情况。如果你想提供你的库应该可以从C和C++调用的功能,你的库接口应该是C兼容的。查看Using C++ library in C code以获得如何在C界面中打包C++函数的答案。

  2. 通常建议您不要将自己的库与所有依赖包打包在一起,因为它会生成繁重的二进制文件,并且会破坏共享库的用途,除非您打包的依赖项很小。然而,就你而言,如果你想这样做,你需要创建静态共享库。但是,不可能从两个共享库创建。你需要两个对象文件。请参阅Merge multiple .so shared libraries获取答案。

+0

感谢您的回答,但对于我的情况,我不希望应用程序了解我对共享内存的使用情况,这不是他的担忧。 – IoT

+0

是的..没错。为此,你需要实现包装函数来为你做。例如,您将需要包装函数来接受和返回C数据类型而不是C++数据类型。 –