I have a C function that I would like to call from C++. I couldn't use "extern "C" void foo()
" kind of approach because the C function failed to be compiled using g++. But it compiles fine using gcc. Any ideas how to call the function from C++?
相关问题
- Sorting 3 numbers without branching [closed]
- Multiple sockets for clients to connect to
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
I agree with Prof. Falken's answer, but after Arne Mertz's comment I want to give a complete example (the most important part is the
#ifdef __cplusplus
):somecode.h
somecode.c
othercode.hpp
othercode.cpp
Then you follow Prof. Falken's instructions to compile and link.
This works because when compiling with
gcc
, the macro__cplusplus
is not defined, so the headersomecode.h
included insomecode.c
is like this after preprocessing:and when compiling with
g++
, then__cplusplus
is defined, and so the header included inothercode.cpp
is now like that:This answer is inspired by a case where Arne's rationale was correct. A vendor wrote a library which once supported both C and C++; however, the latest version only supported C. The following vestigial directives left in the code were misleading:
This cost me several hours trying to compile in C++. Simply calling C from C++ was much easier.
The ifdef __cplusplus convention is in violation of the single responsibility principle. A code using this convention is trying to do two things at once:
It's like trying to write in both American and British English at the same time. This is unnecessarily throwing an #ifdef __thequeensenglish spanner #elif __yankeeenglish wrench #else a useless tool which makes the code harder to read #endif into the code.
For simple code and small libraries the ifdef __cplusplus convention may work; however, for complex libraries it is best to pick one language or the other and stick with it. Supporting one of the languages will take less maintenance than trying to support both.
This is a record of the modifications I made to Arne's code to get it to compile on Ubuntu Linux.
foo.h:
foo.c
bar.cpp
Makefile
Let me gather the bits and pieces from the other answers and comments, to give you an example with cleanly separated C and C++ code:
The C Part:
foo.h:
foo.c
Compile this with
gcc -c -o foo.o foo.c
.The C++ Part:
bar.cpp
Compile this with
g++ -c -o bar.o bar.cpp
And then link it all together:
Rationale: The C code should be plain C code, no
#ifdef
s for "maybe someday I'll call this from another language". If some C++ programmer calls your C functions, it's their problem how to do that, not yours. And if you are the C++ programmer, then the C header might not be yours and you should not change it, so the handling of unmangled function names (i.e. theextern "C"
) belongs in your C++ code.You might, of course, write yourself a convenience C++ header that does nothing except wrapping the C header into an
extern "C"
declaration.Compile the C code like this:
Then the C++ code like this:
Then link them together, with the C++ linker:
You also have to tell the C++ compiler a C header is coming when you include the declaration for the C function. So
othercode.cpp
begins with:somecode.h
should contain something like:(I used gcc in this example, but the principle is the same for any compiler. Build separately as C and C++, respectively, then link it together.)