C and C++ linkage with extern "C"

10,382

Solution 1

To call it in C, all you need to do is call it normally. Because you told the compiler to use the C calling conventions and ABI with extern "C", you can call it normally:

func(args);

To compiler, use this for the C++:

g++ -c -o myfunc.o myfunc.cpp

Then this for the C:

gcc -c -o main.o somec.c

Than link:

g++ -o main main.o myfunc.o

Make sure that the C++ header for the function uses ONLY C CONSTRUCTS. So include things like <vector> in the .cpp file instead.

Solution 2

You call the function from C in the normal way. However, you need to wrap the extern "C" in an preprocessor macro to prevent the C compiler from seeing it:

#ifndef __cplusplus
extern "C"
#endif
void func(bool first, float min, float* state[6], float* err[6][6]);

Assuming you're working with GCC, then compile the C code with gcc, compile the C++ code with g++, and then link with g++.

Solution 3

call it in C using

func(/* put arguments here */);

By saying extern "C" you are asking the compiler not to mangle your names. Otherwise, C++ compiler would tend to mangle them (i.e. add additional symbols to make them unique) before the linker.

You'll also want to make sure you have setup to use C calling convention.

Solution 4

//header file included from both C and C++ files

#ifndef __cplusplus
#include <stdbool.h> // for C99 type bool
#endif

#ifdef __cplusplus
extern "C" {
#endif

void func(bool first, float min, float* state[6], float* err[6][6]);

#ifdef __cplusplus
} // extern "C"
#endif

// cpp file
#include "the_above_header.h"
#include <vector>

extern "C" void func(bool first, float min, float* state[6], float* err[6][6]);
{
    //uses vectors and classes and other C++ constructs
}

// c file
#include "the_above_header.h"

int main() {
    bool b;
    float f;
    float *s[6];
    float *err[6][6];
    func(b,f,s,err);
}
Share:
10,382
CodeKingPlusPlus
Author by

CodeKingPlusPlus

Updated on June 09, 2022

Comments

  • CodeKingPlusPlus
    CodeKingPlusPlus almost 2 years

    I have a C++ function defined in a .h file as follows and implemented in a .cpp file:

    extern "C" void func(bool first, float min, float* state[6], float* err[6][6])
    {
        //uses vectors and classes and other C++ constructs
    }
    

    How can I call func in a C file? How do I set up my file architecture / makefile to compile this?

    Thanks!

  • CodeKingPlusPlus
    CodeKingPlusPlus almost 12 years
    I am getting erros from gcc saying cannot include vector since my C file is including the file where func is defined which uses vectors
  • Josh Petitt
    Josh Petitt almost 12 years
    You might just want to compile the whole thing with g++? I've typically seen extern "C" in C++ code when you are building a .dll and want to link to it without having to know the mangled name.
  • Linuxios
    Linuxios almost 12 years
    @CodeKingPlusPlus: Also take a look at the bottom of my answer.
  • Oliver Charlesworth
    Oliver Charlesworth almost 12 years
    @CodeKingPlusPlus: You cannot use C++ features in a header file that's intended to be processed by a C compiler (unless you hide them inside an #ifndef __cplusplus ... #endif).
  • DevSolar
    DevSolar almost 12 years
    @CodeKingPlusPlus: "What do you mean link?" - I fear we have a problem here... check out the -c option in the GCC manuals, and what "linking" is about. Otherwise, no answer you could get here will make sense.
  • BoBTFish
    BoBTFish almost 12 years
    Being horribly picky, it disables c++ mangling, not all mangling (c uses mangling in some cases). blogs.msdn.com/b/oldnewthing/archive/2012/05/25/10310148.asp‌​x
  • Josh Petitt
    Josh Petitt almost 12 years
    @BoBTFish :-) yeah that's why I said "asking" the compiler. +1 for the clarification and hyperlink.
  • Linuxios
    Linuxios almost 12 years
    @CodeKingPlusPlus: The -c option tells the compiler to only compile your code to intermediate object code files (.o) which can then be linked together into an executable by excluding the -c option. Object files allow you to combine C and C++, and impose some separation into different parts of the project. They also allow you to compile only small parts of your code, which is crucial to large projects and systems like make.
  • CodeKingPlusPlus
    CodeKingPlusPlus almost 12 years
    Thanks! When I run the last compile line (gcc -o main main.o myfunc.o) it fails and tells me I have an undefined reference to files I included in myfunc.cpp
  • Linuxios
    Linuxios almost 12 years
    @CodeKingPlusPlus: To what files? What is the exact message?
  • Linuxios
    Linuxios almost 12 years
    @JoshPetitt: In this case, any kind of shared library (.so, .dll, etc.). Because this is GCC, I think that it is probably Linux, and if it isen't, GCC on other platforms still uses .so. (Mac uses it anyway, on Windows you need a Cygwin-like layer).
  • Osman-pasha
    Osman-pasha over 2 years
    Shouldn't the answer be ifdef __cplusplus?