23

I have a c-library which I use in gcc. The library has the extension .lib but is always linked as a static library. If i write a program which uses the library as c-code, everything as a-ok. If I however rename the file to .cpp (doing simple stuff that works in both c/c++) I get undefined reference. These are simple small programs I write for testing purposes so no fancy stuff. I compile using:

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread

The above works like a charm. However:

g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread

or

gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++

results in undefined reference to any function in customlibrary.lib. I tried creating a symbolic link named customlibrary.a but no luck.

Why won't g++ find recognize my library. Unfortunately I have no access to the source code of the libraries but linking a c-lib to c++ should not be a problem right?

Cœur
  • 34,719
  • 24
  • 185
  • 251

3 Answers3

40

Your library appears to have an API that assumes it will be called from C, not C++. This is important because C++ effectively requires that the symbols exported from a library have more information in them than just the function name. This is handled by "name mangling" the functions.

I assume your library has an include file that declares its public interface. To make it compatible with both C and C++, you should arrange to tell a C++ compiler that the functions it declares should be assumed to use C's linkage and naming.

A likely easy answer to test this is to do this:

extern "C" {
#include "customlibrary.h"
}

in your main.cpp instead of just including customlibrary.h directly.

To make the header itself work in both languages and correctly declare its functions as C-like to C++, put the following near the top of the header file:

#ifdef __cplusplus
extern "C" {
#endif

and the following near the bottom:

#ifdef __cplusplus
}
#endif
RBerteig
  • 40,004
  • 7
  • 84
  • 125
4

The C++ compiler performs what is known as name-mangling - the names that appear in your code are not the same ones as your linker sees. The normal way round this is to tell the compiler that certain functions need C linkage:

// myfile.cpp
extern "C" int libfun();    // C function in your library

or do it for a whole header file:

// myfile.cpp
extern "C" {
  #include "mylibdefs.h"      // defs for your C library functions
}
mmx
  • 402,675
  • 87
  • 836
  • 780
2

Does your header file have the usual

#ifdef __cplusplus
extern "C" {
#endif

// ...

#ifdef __cplusplus
} /* extern "C" */
#endif

to give the library functions C linkage explicitly.

.cpp files are compiled with C++ linkage i.e. name mangling by default.

laalto
  • 144,748
  • 64
  • 275
  • 293