Call C++ member function in C

Subrat (C++ windows/Linux)Software Engineer
CERTIFIED EXPERT
Provide training in Advanced C++ and working as a software Engineer since 2003
Published:
Updated:
Edited by: evilrix
This article shows the procedure to call c++ class member function from C source code.

Compiler & OS used:

gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

Linux(Ubuntu-18.04) 


There are three steps involved to achieve this goal.

  1. Create C++ class with member function.
  2. Create a wrapper in C++ which can be used by C code to call C++ member function.
  3. Write C code, use the wrapper to call C++ member function.


Step1:

    i) cppdemo.h

#ifndef CPP_DEMO_H
#define CPP_DEMO_H

class CppDemo {

public:

CppDemo();

void Print(const char * str);

};
#endif 

ii) cppdemo.cpp

#include <iostream>

#include "cppdemo.h"

CppDemo::CppDemo() {

    std::cout << "CPP Demo Constructor Called!!!" << std::endl;
}

void CppDemo::Print(const char *str) {

    std::cout << "I am in C++ code, printing your message: " << str << std::endl;
}

Compile: 

g++ -fpic -shared cppdemo.cpp -o libcppdemo.so

Step2:

i) c_wrapper.h

#ifndef C_WRAPPER_H 
#define C_WRAPPER_H 
 

#ifdef __cplusplus
extern "C" {
#endif

void print(const char *name);

#ifdef __cplusplus
}
#endif

#endif

     

ii)  c_wrapper.cpp

// NULL can be replaced by nullptr(C++11/14/17 support of compiler is needed)


#include <iostream>


#include "c_wrapper.h"
#include "cppdemo.h"

#ifdef __cplusplus
extern "C" {
#endif

static CppDemo* obj = NULL;

void CreateObject() {

	if (obj == NULL) {
		obj = new CppDemo();
	}
}

void DeleteObj() {


  if(obj) {

    obj->Print("Delete called\n");
    delete obj;
    obj = NULL;
  }
}

void print(const char* str) {

    CreateObject();
    obj->Print(str);
    DeleteObj();
}

#ifdef __cplusplus
}
#endif

Compile: 

g++ -fpic -shared c_wrapper.cpp -L. -lcppdemo -o libc_wrapper.so 

Step3:

main.c

#include "c_wrapper.h"

int main() {
  print("Subrat");
  print("Suraj");
  return 0;
}

Setting library path:

export LD_LIBRARY_PATH=$PWD


Compile:

 gcc main.c -L. -lc_wrapper -o output

Run:

./outpt

Output:

CPP Demo Constructor Called!!!
I am in C++ code, printing your message: Subrat
I am in C++ code, printing your message: Delete called

CPP Demo Constructor Called!!!
I am in C++ code, printing your message: Suraj
I am in C++ code, printing your message: Delete called


Conclusion:

This article gives you an idea about how to migrate existing C source code to C++ code.


Here we have created the class "CppDemo" having the member function "Print". We created a shared library of it and it is being used by wrapper class "c_wrapper.cpp". The wrapper class is also built to a shared library which is being used by C souce code.


Note:

You may get a linking error. Something like below

./libc_wrapper.so: undefined reference to `CppDemo::Print(char const*)'
./libc_wrapper.so: undefined reference to `CppDemo::CppDemo()'


You can resolve that by setting the library path by below command (this is the path of your .so files).

export LD_LIBRARY_PATH=$PWD


0
1,319 Views
Subrat (C++ windows/Linux)Software Engineer
CERTIFIED EXPERT
Provide training in Advanced C++ and working as a software Engineer since 2003

Comments (2)

Subrat (C++ windows/Linux)Software Engineer
CERTIFIED EXPERT

Author

Commented:
Since a long time I am not getting any update.
evilrixEngineering Manager
CERTIFIED EXPERT

Commented:
Hi Subrat.

Yes, I see what you mean. That is odd. I'll need to report that to EE to see what they say. Meanwhile, finish up all the other changes and we can take it from there. Is that okay with you?

All the best,

Rix.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.