1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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

Discussion in 'C++' started by poornaMoksha, Nov 27, 2011.

Tags:
  1. poornaMoksha

    poornaMoksha New Member

    Joined:
    Jan 29, 2011
    Messages:
    150
    Likes Received:
    33
    Trophy Points:
    0
    Occupation:
    Software developer
    Location:
    India
    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!!!
     

Share This Page