我有用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
我的问题是:
这是构建可在C&amp; C中使用的库的正确方法吗? C ++?
我的共享库使用Boost Interprocess库,它是标准POSIX共享内存调用的包装器。每当我尝试将此共享库链接到任何应用程序时,我都应该在应用程序中再次包含lrt
。所以我的问题是可以将共享库静态链接到lrt
库,而无需在使用我的共享库的所有应用程序中包含lrt
吗?
答案 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)
让我逐一回答你的问题:
显然,根据您的用例,您希望混合使用哪种代码。如果要提供可以从C和C ++调用库的功能,则库接口应该与C兼容。查看Using C++ library in C code,了解如何在C接口中包装C ++函数。
通常建议您不要使用所有依赖项打包库,因为它会产生大量二进制文件并且会破坏共享库的用途,除非您打包的依赖项很小。但是,在您的情况下,如果您想这样做,则需要创建静态共享库。但是,无法从两个共享库创建。您需要两者的目标文件。请参阅Merge multiple .so shared libraries获取答案。