Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/articles/cpp-tutorials/)
-   -   Using extern "C" to call C function from C++ and vice versa (http://www.go4expert.com/articles/using-extern-c-c-function-cpp-vice-versa-t27221/)

poornaMoksha 27Nov2011 11:27

Using extern "C" to call C function from C++ and vice versa
 
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!!!


All times are GMT +5.5. The time now is 07:59.