C and C++ linkage with extern "C"
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);
}
CodeKingPlusPlus
Updated on June 09, 2022Comments
-
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 almost 12 yearsI 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 almost 12 yearsYou 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 almost 12 years@CodeKingPlusPlus: Also take a look at the bottom of my answer.
-
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 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 almost 12 yearsBeing 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.aspx
-
Josh Petitt almost 12 years@BoBTFish :-) yeah that's why I said "asking" the compiler. +1 for the clarification and hyperlink.
-
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 almost 12 yearsThanks! 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 almost 12 years@CodeKingPlusPlus: To what files? What is the exact message?
-
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 over 2 yearsShouldn't the answer be
ifdef __cplusplus
?