This is something that makes me fairly perplexed.
I have a C++ file that implements a set of functions, and a header file that defines p开发者_运维问答rototypes for them.
When building with Visual Studio or MingW-gcc, I get linking errors on two of the functions, and adding an 'extern "C"' qualifier resolved the error. How is this possible?
Header file, "some_header.h":
// Definition of struct DEMO_GLOBAL_DATA omitted
DWORD WINAPI ThreadFunction(LPVOID lpData);
void WriteLogString(void *pUserData, const char *pString, unsigned long nStringLen);
void CheckValid(DEMO_GLOBAL_DATA *pData);
int HandleStart(DEMO_GLOBAL_DATA * pDAta, TCHAR * pLogFileName);
void HandleEnd(DEMO_GLOBAL_DATA *pData);
C++ file, "some_implementation.cpp"
#include "some_header.h"
DWORD WINAPI ThreadFunction(LPVOID lpData) { /* omitted */ }
void WriteLogString(void *pUserData, const char *pString, unsigned long nStringLen) { /* omitted */ }
void CheckValid(DEMO_GLOBAL_DATA *pData) { /* omitted */ }
int HandleStart(DEMO_GLOBAL_DATA * pDAta, TCHAR * pLogFileName) { /* omitted */ }
void HandleEnd(DEMO_GLOBAL_DATA *pData) { /* omitted */ }
The implementations compile without warnings, but when linking with the UI code that calls these, I get a normal
error LNK2001: unresolved external symbol "int __cdecl HandleStart(struct _DEMO_GLOBAL_DATA *, wchar_t *)
error LNK2001: unresolved external symbol "void __cdecl CheckValid(struct _DEMO_MAIN_GLOBAL_DATA *
What really confuses me, now, is that only these two functions (HandleStart and CheckValid) seems to be built with C linkage. Explicitly adding "extern 'C'" declarations for only these two resolved the linking error, and the application builds and runs. Adding "extern 'C'" on some other function, such as HandleEnd, introduces a new linking error, so that one is obviously compiled correctly.
The implementation file is never modified in any of this, only the prototypes.
The error indicates that nothing is wrong with your implementation file or header (as used by the implementation file) - the link error strongly suggests that the functions actually generated were generated with c++ linkage - Its the UI file thats incorrectly looking for the C-Linkage versions of the functions. Patching the definitions in the header is patching your implementation to conform to the probably incorrect demands of the UI, rather than the other way around.
Your UI file is either a .m or .c file, OR , if your UI file is a .cpp file you have dome something like:
// ui.cpp
extern "C" {
#include "some_header.h"
}
Of course, if your UI file is a .c file - you either need to change it to cpp, OR explicitly define the functions with C-linkage so they can be called from C.
Could the function names conflict with names declared in a header?
Do you get the same problem if you give the functions different names?
精彩评论