简体   繁体   中英

C wrapper for C++ Library, problems with iostream and gcc

I want to use this C++ Library in C-Code (and compile the code with gcc): https://github.com/fairlight1337/libcflie

To do that I added Wrapper functions to CCrazyflie.h, CCrazyflie.cpp, CCrazyRadio.h and CCrazyRadio.cpp (all functions I want to use are in those Files):

Added to CCrazyRadio.h:

extern "C"
{
  CCrazyRadio* newCCrazyRadio(string strRadioID);
  void deleteCCrazyRadio(CCrazyRadio* cr);
  int CCrazyRadio_startRadio(CCrazyRadio* cr);
}

Added to CCrazyRadio.cpp:

extern "C"
{
   CCrazyRadio* newCCrazyRadio(string strRadioID) {return new CCrazyRadio(strRadioID);}
   void deleteCCrazyRadio(CCrazyRadio* cr) {delete cr;}
   int CCrazyRadio_startRadio(CCrazyRadio* cr) {if(cr->startRadio()) return 1; else return 0;}
}

I did the same thing for the functions in CCrazyflie.h and CCrazyflie.cpp.

I can use the wrappers in C-code and they work when compiled with g++, but when compiling with gcc the compiler complains that it doesn't know iostream (included in CCrazyflie.h and CCrazyRadio.h which are both included in my C-code).

Am I doing this right? How can I make gcc find iostream (and the other C++ libraries that are included)? If needed I would be happy to show you more of the code, I just tried to keep the post short.

Thanks in advance for any help! Regards, Daniel

The problem is not the linker as some have suggested, or that the wrappers need to be compiled with a C++ compiler (although they do).

The issue is that the C file includes the header that defines the wrappers, and the wrapper functions take types that the C language doesn't have - eg string. The extern statement tells the C++ compiler not to mangle the names, but doesn't magically make anything inside legal C.

So, your wrapper functions need to be defined to take C types, so your

CCrazyRadio* newCCrazyRadio(string strRadioID);

becomes something like

CCrazyRadio* newCCrazyRadio(char * radioId);

And internally to newCCrazyRadio you can construct a string to hold your radioID, if needed. If CCrazyRadio is a class, you will still have troubles though. So, if this is just being returned as some sort of handle, you could perhaps replace with a void*

You still need the extern 'C' .

You will also need to ensure that the header containing the wrapper functions ONLY includes C header files. Even if gcc (in C mode) can find them, they will not contain valid C code. This means it cannot include iostream etc.

One further thing, I recall that C doesnt understand the extern C syntax, so you may need to wrap that with a conditional compiliation block eg (you will need to check the syntax your self)

#ifdef _CPLUSPLUS_ // Check this bit
extern 'C'
{
#endif
//Put your prototype wrappers here

#ifdef _CPLUSPLUS
}
#endif

This basically means that only the C++ compiler will see the extern C directive.

(Update: this answer is wrong due to misunderstanding of the question. The discussion in the comments may still be worthwile, though)

It's not what you compile with, it's what you link with. The C code compiled with gcc needs to be linked with g++ to have access to C++ system libraries. If any .so or .lib files in your project contain C++ code, you need to link with g++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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