There are two object files. On of them contains definition (the body) of a function. This object file was compiled with C++ compiler, so the function name is mangled. The second object file references (calls) the function from the first object file. However, the second object file was compiled with C compiler, so the function name is not mangled. When linking these two object files, there is an error for undefined symbol. It is not possible to change the source files so that the C++ object file uses extern "C" definitions and doesn't mangle the function name. It is however possible to write whatever glue (wrapper) code, compile it with C++ compiler and link together with those object files. Here is a simple example:
$ cat file1.cpp
int fun(int in1, int in2) {
return in1+in2;
}
$ cat file2.c
#include <stdio.h>
int fun(int, int);
int main() {
printf("%d\n",fun(3, 4));
return 0;
}
These two files are compiled into objects without any possibility to change those:
g++ -c file1.cpp -o file1.o
gcc -c file2.c -o file2.o
Writing a glue code seems like a simple task, but the problem is that we have to export function name to C and import it from C++ at the same time. The only solution i could come up with is to write two wrappers. One of them basically renames the C++ function, and the other one exposes the renamed function to C:
$ cat glue.cpp
int cppfun(int, int);
#ifdef __cplusplus
extern "C" {
#endif
int fun(int in1, int in2) {
return cppfun(in1, in2);
}
#ifdef __cplusplus
}
#endif
$ cat gluecpp.cpp
int fun(int, int);
int cppfun(int in1, int in2) {
return fun(in1, in2);
}
Compile and link those wrappers together with original objects:
g++ -c glue.cpp -o glue.o
g++ -c gluecpp.cpp -o gluecpp.o
g++ file1.o file2.o glue.o gluecpp.o -o exe.out
What do you think, guys, is there another way? This have become simply an academic interest now for me :)
This glue works with GCC.
extern "C"
{
static int fun_c(int, int) __attribute__ ((weakref ("fun")));
};
int fun(int a, int b)
{
return fun_c(a, b);
}
No special linker flags needed.
Update: the above code does it in the opposite direction, C++-calling-C. The requested direction goes like this:
static int fun_cpp(int, int) __attribute__ ((weakref ("manglednameforfun")));
extern "C" int fun(int a, int b)
{
return fun_cpp(a, b);
}
You need to know the mangled name for "fun" obviously.
As a side note, no solution can be standard-conforming, as the standard dows not allow to have two functions with the same name and different language linkages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With