0

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?

6
  • 3
    Um just a notice, but libc might a bit dangerous name to use. I am not sure what name it uses on system, but generally there is something named libc already. Also what error do you get? Might be useful information. Commented Apr 29, 2014 at 23:41
  • FYI, C++ has a mechanism to create C-callabel functions extern "C", C does not have a facility to call C++ functions. Commented Apr 29, 2014 at 23:44
  • 1
    @Deduplicator But OP uses it. It is the only content of libc.h. Is it used wrongly? The only problem I see so far is libcpp.h which existence is not confirmed. It seems like Object should be defined there. But its been years since I compiled an .so by hand. I'm not good enough to guess without an error message. Commented Apr 29, 2014 at 23:47
  • Q1: do you have source code to the C++ library? If yes, things may be a bit easier; if not then there is a lot more trickery you have to do. Q2: if you don't have C++ library code, do you have an understanding of name mangling in C++? Commented Apr 29, 2014 at 23:50
  • @luk32: Yes, it is, because the header is no longer C. Commented Apr 29, 2014 at 23:52

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

3 Comments

Not sure where to put it, but I choose your answer. So extern "C" will produce an error with c compiler and the c program won't compile. Is that it?
Yes. That's the important part.
Now its all clear. Sorry for stupid questions, but without error and unresponsive OP, and lack of experience it was quite hard to get. Thanks for clarifying everything.
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.

2 Comments

So this is what @Deduplicator was trying to tell. lol. Call me stupid but code is so much more understandable than words...
Thanks everyone, I was able to get it to run. Kerrek's solution worked and I had to compile with 'g++ -Wall test.c libc.cpp -L/opt/lib -lc -o test'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.