Today, I add two c files(one is fun.c, the other is its header file fun.h) to a c++ project, because I want to call a function(fun1) residing in the C source file(fun.c) in a c++ source file (main.cpp) of the C++ project. Then the error occurs.
main.obj:-1: error: LNK2019: unresolved external symbol “void __cdecl fun1(void)” (?fun1@@YAXXZ) referenced in function _main
This error is due to so called name mangling. The C++ compiler compiling main.cpp generates a function reference in main.o, however, the reference is not “fun1” but ?fun1@@YAXXZ, which is called name mangling. When compiling fun.c, the C compiler may generate the function name of fun1 simply as “fun1″(or another mangled name) in fun.o. So, the linker cannot find a match in the function implementation in fun.o for the function reference in main.o, thus reports the error.
There are two solutions to this problem.
using C++ compiler to compile the C source file
You can rename fun.c to fun.cpp. Then, the C++ compiler instead of C compiler will be invoked to compile fun.cpp and generate the same mangled function name as in main.o, thus the linker can find the match.
This method may not work because your C code may produce the following errors:
error: C2440: ‘initializing’: cannot convert from ‘void *’ to ‘char *’
error: C2440: ‘initializing’: cannot convert from ‘const char [20]’ to ‘char *’
This is because C++ compiler may not support implicit type conversion and you’ll have to cast types forcefully.
tell C++ compiler not to mangle function names
You can guide the C++ compiler to generate C reference names when compiling main.cpp. Specifically, you can enclose the declaration of the function with extern “C”{…},i.e.,
#ifdef __cplusplus extern "C"{ #endif void fun1( ); #ifdef __cplusplus } #endif
This way, the calling of fun1 will simply generate the reference as “fun1″(or other type of C name mangling).
Reference: https://stackoverflow.com/questions/18636599/c-error-lnk2019-unresolved-external-symbol