How to call C++ function from C? How to call C++ function from C? c c

How to call C++ function from C?


You need to create a C API for exposing the functionality of your C++ code. Basically, you will need to write C++ code that is declared extern "C" and that has a pure C API (not using classes, for example) that wraps the C++ library. Then you use the pure C wrapper library that you've created.

Your C API can optionally follow an object-oriented style, even though C is not object-oriented. Ex:

 // *.h file // ... #ifdef __cplusplus #define EXTERNC extern "C" #else #define EXTERNC #endif typedef void* mylibrary_mytype_t; EXTERNC mylibrary_mytype_t mylibrary_mytype_init(); EXTERNC void mylibrary_mytype_destroy(mylibrary_mytype_t mytype); EXTERNC void mylibrary_mytype_doit(mylibrary_mytype_t self, int param); #undef EXTERNC // ... // *.cpp file mylibrary_mytype_t mylibrary_mytype_init() {   return new MyType; } void mylibrary_mytype_destroy(mylibrary_mytype_t untyped_ptr) {    MyType* typed_ptr = static_cast<MyType*>(untyped_ptr);    delete typed_ptr; } void mylibrary_mytype_doit(mylibrary_mytype_t untyped_self, int param) {    MyType* typed_self = static_cast<MyType*>(untyped_self);    typed_self->doIt(param); }


I would do it in the following way:

(If working with MSVC, ignore the GCC compilation commands)

Suppose that I have a C++ class named AAA, defined in files aaa.h, aaa.cpp, and that the class AAA has a method named sayHi(const char *name), that I want to enable for C code.

The C++ code of class AAA - Pure C++, I don't modify it:

aaa.h

#ifndef AAA_H#define AAA_Hclass AAA {    public:        AAA();        void sayHi(const char *name);};#endif

aaa.cpp

#include <iostream>#include "aaa.h"AAA::AAA() {}void AAA::sayHi(const char *name) {    std::cout << "Hi " << name << std::endl;}

Compiling this class as regularly done for C++. This code "does not know" that it is going to be used by C code. Using the command:

g++ -fpic -shared aaa.cpp -o libaaa.so

Now, also in C++, creating a C connector:

Defining it in files aaa_c_connector.h, aaa_c_connector.cpp. This connector is going to define a C function, named AAA_sayHi(cosnt char *name), that will use an instance of AAA and will call its method:

aaa_c_connector.h

#ifndef AAA_C_CONNECTOR_H #define AAA_C_CONNECTOR_H #ifdef __cplusplusextern "C" {#endif void AAA_sayHi(const char *name);#ifdef __cplusplus}#endif#endif

aaa_c_connector.cpp

#include <cstdlib>#include "aaa_c_connector.h"#include "aaa.h"#ifdef __cplusplusextern "C" {#endif// Inside this "extern C" block, I can implement functions in C++, which will externally //   appear as C functions (which means that the function IDs will be their names, unlike//   the regular C++ behavior, which allows defining multiple functions with the same name//   (overloading) and hence uses function signature hashing to enforce unique IDs),static AAA *AAA_instance = NULL;void lazyAAA() {    if (AAA_instance == NULL) {        AAA_instance = new AAA();    }}void AAA_sayHi(const char *name) {    lazyAAA();    AAA_instance->sayHi(name);}#ifdef __cplusplus}#endif

Compiling it, again, using a regular C++ compilation command:

g++ -fpic -shared aaa_c_connector.cpp -L. -laaa -o libaaa_c_connector.so

Now I have a shared library (libaaa_c_connector.so), that implements the C function AAA_sayHi(const char *name). I can now create a C main file and compile it all together:

main.c

#include "aaa_c_connector.h"int main() {    AAA_sayHi("David");    AAA_sayHi("James");    return 0;}

Compiling it using a C compilation command:

gcc main.c -L. -laaa_c_connector -o c_aaa

I will need to set LD_LIBRARY_PATH to contain $PWD, and if I run the executable ./c_aaa, I will get the output I expect:

Hi DavidHi James

EDIT:

On some linux distributions, -laaa and -lstdc++ may also be required for the last compilation command. Thanks to @AlaaM. for the attention


You will have to write a wrapper for C in C++ if you want to do this. C++ is backwards compatible, but C is not forwards compatible.