I am trying to compile some legacy C/C++ code on Mac OS X with gcc 4.2. that was originally written on Windows using Visual Studio. I am compiling a static library that is being linked against by other code, but I've been encountering some hard to understand linker errors.
When I try to compile some source code against the static library, the linker gives me the following errors:
Undefined symbols for architecture i386:
"_read_float", referenced from:
_sub_token_values in libcompengine.a(alparce.o)
The method read_float is in the library, and it is being compiled. But when I dump the symbols in the library using nm, I see that under libcompengine.a(alparce.o) the method _read_float appears as undefined:
U _read_float
And further down in the file where read_float is supposed to be defined, it appears with a mangled name:
00000686 t __ZL10read_floatPKj
Can anyone give me any hints as to why this method isn't being开发者_运维百科 resolved correctly? I spent half a day trying various gcc compiler and source flags, but unfortunately, I haven't hit on a winning combination yet.
If you're planning on using a C++ library to interface with C, it's important that you mark the functions that the C program will be calling are marked appropriately.
I've done the following (though there are other ways of doing it)
#ifndef INCLUDE_FILE_NAME_H
#define INCLUDE_FILE_NAME_H
// Insert this before any global function defintitions
#ifdef __cplusplus
extern "C" {
#endif
float read_float();
// Insert after all global function defintions
#ifdef __cplusplus
}
#endif
#endif
What this does is it tells the compiler that all of the external function definitions between the extern "C" {} lines should use C linkage. It only adds the extra definition when compiled with C++. Another option is to do something like the below, which basically lets you specify function-by-function which should use C linkage, and which don't.
#ifdef __cplusplus
#define C_LINKAGE "C"
#else
#define C_LINKAGE
#endif
extern C_LINKAGE float read_float();
精彩评论