Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. The original library contained data-types that are only valid for C++ like std::string and std::vector as follow:

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:

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:

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++?

  2. My shared library use Boost Interprocess library which is a wrapper for the standard POSIX shared memory calls. Whenever I try to link this shared library to any application, I should include the lrt again in the application. 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?


1 Answers

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. In particular a std::string is not a char * and vector is not int *.

For example if the API defines a C++ funciton like

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

you'll need to implement a wrapper function (compiled and link as C++) like

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++.

like image 122
dohashi Avatar answered Dec 20 '25 19:12

dohashi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!