Reputation: 27
Is there any way to call a C++ function from a C source file , without using extern "C" prior to the function declaration in the C++ file e.g :
//C++ source file
extern "C" void func_name();
void func_name()
{
....
}
Upvotes: 2
Views: 1415
Reputation: 35154
You could write a separate translation unit, let's say mycppunit.cpp
containing your void func_name()
implementation without any extern "C"
declarations. Compile this translation unit into a binary using a C++ compiler, yielding, for example, a mycppunit.o
binary; then, use a command line tool like nm
to find out how the function name has been mangled: For example:
nm mycppunit.o | grep func_name
would give something like
000000010006a920 T __Z9func_namev
Then you may assume that there will be a function void _Z9func_namev()
available, and you can write in a translation unit, e.g. `my_c_program.c, the following:
void _Z9func_namev();
int main() {
_Z9func_namev();
}
Compiling this with a C compiler and linking it together with the mycppunit.o
will give the desired result.
Hope it is what you are looking for.
Upvotes: 1
Reputation: 140540
I'm not aware of any combination of C and C++ compilers that provide an officially supported way to do this. You're supposed to use extern "C" in the C++-side header files.
However, perhaps you have to anyway; I can think of several reasons other than homework, such as when you've got a third-party C++ library with an interface that could be invoked from C but the developers neglected to put extern "C" in the headers, and you can't recompile it.
There is usually an unofficial way to do it: you have to find out the mangled name of the C++ function, and any hidden parameters that it has (this
is almost always treated as a hidden first parameter, and there may be others). You then write a declaration on the C side using the mangled name and the full parameter list.
Here is a very simple example that will work with GCC on most operating systems and CPUs:
/* file1.cpp */
#include <cstdio>
void foo()
{
puts("hello from foo");
}
/* file2.c */
#include <stdio.h>
extern void _Z3foov(void);
int main(void)
{
puts("hello from main");
_Z3foov();
return 0;
}
Because this is homework I am not going to give you a more complicated example, but I am going to point you at the so-called "Itanium C++ ABI", which specifies how the mangling and the hidden parameters work with GCC and Clang on most operating systems and CPUs. (Be aware that MSVC uses a completely different, undocumented, scheme. I have heard rumors that Clang can optionally use MSVC's scheme now but I'm not sure I believe it, considering how gargantuan a reverse-engineering job it would have been. ;-)
(In case you're wondering, mangled names are how function and operator overloading are implemented in the linker. If my file1.cpp
had defined both void foo(void)
and void foo(int)
, that would have produced an object file exporting the mangled names _Z3foov
and _Z3fooi
.)
Upvotes: 2
Reputation: 146910
The only way to not use extern "C" directly is to manually determine the mangled name and call that from C; which is essentially just doing extern "C" but manually. There's no point or purpose or alternative method with any merit whatsoever.
Upvotes: 2