我有一个用 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 中,我们没有字符串和 vector ,这两种数据类型应该修改如下:
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 和 C++ 中使用的库的正确方法吗?
我的共享库使用 Boost Interprocess 库,它是标准 POSIX 共享内存调用的包装器。每当我尝试将此共享库链接到任何应用程序时,我都应该在应用程序中再次包含
lrt
。所以我的问题是,是否可以将共享库静态链接到lrt
库,而无需在使用我的共享库的所有应用程序中包含lrt
?
最佳答案
如果你想让它工作,你将需要构建一个 C++ 接口(interface)库,它实现一个基于 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" block 中声明您的包装函数,这样名称修饰将是 C 风格而不是 C++。
关于c++ - 将 C 程序链接到 C++ 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24806334/