简体   繁体   English

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

[英]Linking C program to C++ Shared Library

I have shared library written in C++ which provides some APIs calls for different applications written in C++ too, now I want to use this library inside C programs. 我有一个用C ++编写的共享库,它为用C ++编写的不同应用程序提供了一些API调用,现在我想在C程序中使用这个库。 The original library contained data-types that are only valid for C++ like std::string and std::vector as follow: 原始库包含的数据类型只对C ++有效,如std :: string和std :: vector,如下所示:

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

These data-types are being used as input parameters for the APIs: 这些数据类型用作API的输入参数:

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

But in C, we don't have string nor vector and these two data-types should be modified as follow: 但在C语言中,我们没有字符串和向量,这两种数据类型应该修改如下:

typedef char*   IPAddress;
typedef int*    SDLIST;

I tried to do the following changes in my code: 我试着在我的代码中进行以下更改:

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

My questions are: 我的问题是:

  1. Is this a correct way to build a library that can be used in both C & C++? 这是构建可以在C&C ++中使用的库的正确方法吗?

  2. My shared library use Boost Interprocess library which is a wrapper for the standard POSIX shared memory calls. 我的共享库使用Boost Interprocess库,它是标准POSIX共享内存调用的包装器。 Whenever I try to link this shared library to any application, I should include the lrt again in the application. 每当我尝试将此共享库链接到任何应用程序时,我都应该在应用程序中再次包含lrt So my question is it possible to link the shared library statically to the lrt library without having the need to include the lrt in all applications that use my shared library? 所以我的问题是可以将共享库静态链接到lrt库而无需在使用我的共享库的所有应用程序中包含lrt吗?

If you want this to work you are going to need to build a C++ interface library that implements a C based API that converts the C datatypes into C++ datatypes. 如果您希望这个工作,您将需要构建一个C ++接口库,该库实现基于C的API,将C数据类型转换为C ++数据类型。 In particular a std::string is not a char * and vector is not int *. 特别是std :: string不是char *而vector不是int *。

For example if the API defines a C++ funciton like 例如,如果API定义了类似的C ++函数

bool CPPAPIFunction( std::string str, std::vector<int> vec )

you'll need to implement a wrapper function (compiled and link as C++) like 你需要实现一个包装器函数(编译和链接为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 );
}

Also don't forget to declare your wrapper function in a extern "C" block, so that the name mangling will be C style not C++. 另外不要忘记在extern“C”块中声明你的包装函数,这样名称mangling将是C风格而不是C ++。

Let me answer your questions one by one: 让我逐一回答你的问题:

  1. Obviously, it is as per your use case what kind of code you want to mix. 显然,根据您的用例,您希望混合使用哪种代码。 If you want to provide capability that your library should be callable from C and C++, your library interface should be C compatible. 如果要提供可以从C和C ++调用库的功能,则库接口应该与C兼容。 Look Using C++ library in C code for an answer to how to wrap your C++ functions in a C interface. 在C代码中查看使用C ++库,以获得如何在C接口中包装C ++函数的答案。

  2. It is generally advised that you do not pack your library with all your dependencies because it makes a heavy binary and defeats the purpose of shared libraries, unless the dependencies you are packing are small. 通常建议您不要使用所有依赖项打包库,因为它会产生大量二进制文件并且会破坏共享库的用途,除非您打包的依赖项很小。 However, in your case, if you want to do that, you need to create static shared library. 但是,在您的情况下,如果您想这样做,则需要创建静态共享库。 However, it is not possible to create from two shared libraries. 但是,无法从两个共享库创建。 You need object files for both of them. 您需要两者的目标文件。 See Merge multiple .so shared libraries for an answer. 请参阅合并多个.so共享库以获取答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM