Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call a C++ function from C? [duplicate]

Tags:

c++

c

I have a header declaring functions that take pointers to C++ objects as parameters. The implementaton is in a seperate C++ file. How can I include this header in C and use the functions in C even though the arguments need to be C++ object pointers?

like image 957
CheedleBoy Avatar asked Dec 16 '22 20:12

CheedleBoy


2 Answers

Unfortunately, my first attempt answered the wrong question....

For the question you did ask...

You can, as someone point out, pass around void *'s. And that's what I would also recommend. As far as C is concerned, pointers to C++ objects should be totally opaque.

C++ functions can be labeled extern "C" as well if they are in the global namespace. Here is an example:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#endif

extern int myfunction(int, void *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, void *vobptr)
{
    ClassType *ob = static_cast<ClassType *>(vobptr);
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, void *opaque_classtype_ptr) {
    myfunction(x, opaque_classtype_ptr);
    /* do stuff with buf */
}

The other option is to do basically the same thing with creative use of typedefs in C. This, IMHO, is quite ugly, but here is an example anyway:

myfunc.hpp:

#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType;  /* This is incredibly ugly. */
#endif

extern int myfunction(int, ClassType *ob);

#ifdef __cplusplus
}
#endif

myfunc.cpp:

#include "myfunc.hpp"

void myfunction(int x, ClassType *ob)
{
    // Do stuff with ob
}

afoofile.c

#include "myfunc.hpp"

void frobble(int x, ClassType *opaque_classtype_ptr) {
    myfunction(x, opaque_classtype_ptr);
    /* do stuff with buf */
}
like image 122
Omnifarious Avatar answered Jan 01 '23 06:01

Omnifarious


If your C code just needs to pass the pointers around, and eventually pass it back to some C++ that'll actually deal with the object it points to, you should be able to use a void * in the C code, and cast back to T * when it goes back into C++.

If you plan on the C code actually using the pointer, you're pretty much stuck with reverse engineering what your compiler happens to do, and trying to emulate it closely enough to make things work. Even at best, this is going to be ugly and fragile.

like image 44
Jerry Coffin Avatar answered Jan 01 '23 05:01

Jerry Coffin