Using extern "C" to call C function from C++ and vice versa

poornaMoksha's Avatar author of Using extern "C" to call C function from C++ and vice versa
This is an article on Using extern "C" to call C function from C++ and vice versa in C++.
Being an experienced C/C++ developer, sometimes there are modules in which the code layer which interact with the system is written in C while the layer above it is written in C++. Have you ever thought of how these two layers (one written in C and other in C++) interact? What if we want to call a function to/from C/C++ to C++/C layer. Well, lets understand the concept of mixing C/C++ code today.

Compiling C code using C++ compiler



Well, fortunately there is not much of a difficulty in compiling a C code with a C++ compiler except that you need to keep this thing in mind that C++ compiler could complain on the coding style as some specifications have changed from C to C++.

We will understand but first lets compile a C Code using C++ :

Code:
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
 
 
int main() 
{ 
 
   printf("\n Hello World\n"); 
 
   return 0; 
}
So we see that the above written code is a pure C code which should print 'Hello World' on execution.
Now lets compile and run the code :

Code:
~/practice $ g++ -Wall segfault.c -o segfault 
~/practice $ ./segfault  
 
 Hello World
So we see that we compiled the code with gnu C++ compiler g++ and it compiled successfully. When we executed the binary, the output came as expected.

Now, lets focus on the other part that I mentioned earlier. That is, though C++ compiler can compile C code but since C++ compiler has its own rules so there could be some changes in the C code to comply it with C++ standards. For example, consider this :

Code:
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
 
 
int main() 
{ 
 
   printf("\n Hello World\n"); 
 
   char *p = malloc(10); 
 
   free(p); 
 
   return 0; 
}
The code above is a valid C code but when I used g++ to compile it, I got :

Code:
~/practice $ g++ -Wall segfault.c -o segfault 
segfault.c: In function ‘int main()’: 
segfault.c:11: error: invalid conversion from ‘void*’ to ‘char*’
We see that there was an error saying that malloc() returns a void* but you are capturing it in char*, hence this operation is invalid. Well, to cut the long explanation short, C++ compiler expects explicit typecasting while using malloc while C compiler does not. Now since we are compiling C code with C++ compiler so we need to comply with C++ coding standards. Hence the code was changed to :

Code:
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
 
 
int main() 
{ 
 
   printf("\n Hello World\n"); 
 
   char *p = (char*)malloc(10); 
 
   free(p); 
 
   return 0; 
}
We added an explicit typecast to the return of malloc() and now when I compile and execute the code above :

Code:
$ g++ -Wall segfault.c -o segfault 
~/practice $ ./segfault  
 
 Hello World
We see that the code compiled and executed properly.


How to include a non-system C header in C++ code



Well, to do this the only effort required is to use the identifier :

extern "C"

to wrap the C header file inclusion. This helps the C++ compiler to understand that the functions declared/defined in this header are C functions and should be treated accordingly.

For example :

Code:
// In C++ code 
 
extern "C" { 
#include "C_Code.h" 
           } 
 
// Now call any function declared/defined in C_Code.h in this C++ file 
... 
... 
...
Another possible way of including a C header is to bring in the identifier extern "C" onto the top of your header file and wrap around all the
file. For example :

Paste this as starting of your header :

Code:
#ifdef __cplusplus 
 extern "C" { 
 #endif
and this at the end of your header :

Code:
 #ifdef __cplusplus 
 } 
 #endif

Calling a non-system C function from C++ code



Suppose you have a C function which you want to call from a c++ code but somehow you do not want to include the C header where the function is declared. In this case we can again use extern "C" to declare the function in C++ source and then we can freely call it from the C++ code.

Lets take an example :

Code:
#include<iostream> 
 
extern "C" { 
void func(); 
} 
 
int main(void) 
{ 
    func(); 
    return 0; 
}
In the above code we have declared a C function func() under the extern "C" tag and made a call to the same function in the main() of this cpp file.

Lets compile the above code :

Code:
~/practice $ g++ -c main.cpp
Since this is a C++ file so we compile it with g++ using -c option to get the object file main.o.

Now, lets see where function func() is defined?

Code:
#include<stdio.h> 
 
void func() 
{ 
    printf("\n Inside func()\n"); 
}
We have the file func.c containing the above code in the same directory as main.c. The above code defines the function func().

Lets compile it :

Code:
 ~/practice $ gcc -c func.c
Since its a C code so we used gcc to compile it. The output we got is func.o

Now, lets link these two object files and execute the executable:

Code:
~/practice $ g++ func.o main.o -o func 
~/practice $ ./func 
 
 Inside func()
Whola!!!....the object files linked correctly and on execution, the C function func() got called from cpp code and executed correctly.



Calling a non-system C++ function from C code



Suppose you have a C++ function that you want to call from C code. In this case again we use extern "C". Lets look at the code :

Code:
#include<iostream> 
#include<stdio.h> 
 
 
extern "C" { 
void func(); 
} 
 
extern "C" void fun() 
{ 
    printf("\n inside fun()\n"); 
} 
 
int main(void) 
{ 
    func(); 
    return 0; 
}
Note that we have defined function fun() with extern "C". Now, lets see the C file code :

Code:
#include<stdio.h> 
 
extern void fun(); 
 
void func() 
{ 
    printf("\n Inside func()\n"); 
    fun(); 
}
Now when you compile and run the code as :

Code:
 
~/practice $ g++ -c main.cpp 
 ~/practice $ gcc -c func.c 
 ~/practice $ g++ main.o func.o -o func 
 ~/practice $ ./func 
 
 Inside func() 
 
 inside fun()
Whola!!!! the cpp function got called from C code.

Conclusion



To conclude, In this article we understood how to mix C/c++ code and saw that how can we call a C function from C++ code and vice versa.

Stay tuned for more!!!