1
votes

I have an static library matrixlib.a which I use to compile some C code. This code is compiled with gcc and it works fine. However I would like to introduce this library into a C++ code and then it's when the problems start. The way I am compiling the C code:

gcc -I/matrix/include -O -Wall example.c -c -o example.o
gfortran example.o /matrix/lib/matrixlib.a -lblas -fopenmp -o example_c

If now we swap gcc for g++:

example.c:(.text+0xf5): undefined reference to `mygemm_solver(int, double const*, double*, double*, int, int)'

being mygemm_solver the function that I am using example.c file. Any ideas of what I am doing wrong?

1
You need to compile c as c, and C++ as C++doctorlove

1 Answers

8
votes

The functions in example.c are probably not declared extern "C", so the C++ compiler is applying name-mangling to the generated symbol name. The Fortran code likely doesn't use the mangled name, so when the linker goes to try to locate it the symbol can't be found.

The first step is to put prototypes of all of the functions you want to "export" from the C/C++ code into a header file. Put this at the top:

#ifdef __cplusplus
extern "C" {
#endif

And then this at the bottom:

#ifdef __cplusplus
}
#endif

This has the effect of automatically applying extern "C" to all functions declared in the header, but only when you are compiling as C++.

However, it's important to note that C and C++ are different languages with differing semantics (for example, in regards to implicitly converting from void *). You should compile C code with a C compiler, and C++ code with a C++ compiler. It is technically possible to write code that is both valid C and C++, and that has the same semantics in both languages, but there is rarely a reason to do this.