Pregunta

My goal is to be able to create a C library wrapper for a Cpp library.

I have:

  1. libcpp.so, a dynamic library written in Cpp by someone else
  2. libc.so, a dynamic library written in C by me to wrap libcpp
  3. test.c, a simple problem to test whether it works.

My problem is that I cannot compile libc.so correctly such that I can access features from libcpp.so from test.c

Example Code:

//libc.h
extern "C" void * createNetwork();

//libc.cpp
#include "libc.h"
#include <libcpp.h>  // <- unsure about this

void * createObject()
{
    Object * foo = new Object();
    void * retval = foo;
    return retval;
}

//test.c
#include <stdio.h>
void * createObject();

int main()
{
    void * bar = createObject();
    return 0;
}

I am compiling using

// COMPILE LIBC
g++ -Wall -fPIC -c libc.cpp -L/opt/lib -llibcpp
gcc -shared -Wl,-soname,libc.so.1 -o libc.so.1.0   *.o
sudo mv libc.so.1.0 /opt/lib
sudo ln -sf /opt/lib/libc.so.1.0 /opt/lib/libc.so.1
sudo ln -sf /opt/lib/libc.so.1.0 /opt/lib/libc.so

// COMPILE TEST.C
gcc -Wall test.c -L/opt/lib -lc -o test

How do I properly include libcpp in libc?

How do I properly include libc in test.c?

Do I need header files in addition to just the dynamic libraries?

¿Fue útil?

Solución 2

The standard mechanism should look something like this:

mylib.h:

#ifndef __cplusplus
extern "C" {
#endif

void * createThing();

void destroyThing(void *);

// more things to operate on the object

#ifndef __cplusplus
}  // extern "C"
#endif

magic_lib.cpp:

#include "magic_thing.hpp"
#include "mylib.h"

void * createThing()
{ return new MagicThing; }

void destroyThing(void * p)
{ delete static_cast<MagicThing *>(p); }

Usage (in C):

#include "mylib.h"

int main(void)
{
    void * p = createThing();

    // ...  use p ...

    destroyThing(p);
}

If you don't like void pointers, you could add a type alias like typedef void * ThingHandle or so.

Otros consejos

The standard way to create functions callable by C and C++ is using preprocessor conditionals looking for __cplusplus, wrapping the whole header in an extern "C" block if it is defined, and not using any C++ extensions.
Thus the header is C and C++. (Optionally one can conditionally add static and non-virtual functions for better C++ integration if __cplusplus is defined)

#ifdef __cplusplus
extern "C" {
#endif
  // Many functions
  // Forward-declarations of used classes using struct like this:
  typedef struct my_class myclass;
  // defined structs may include additional
  //  static and non-virtual member-functions if C++ defined
#ifdef __cplusplus
}
#endif

Then you can build your library in either one, though as it shall facilitate calls to a C++ library you should use C++ for a robust library.
The compiler should warn you if you include the header but forget the extern "C" in C++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top