这让我感到非常困惑。
我有一个实现一组函数的C ++文件,以及一个为它们定义原型的头文件。
使用Visual Studio或MingW-gcc构建时,我得到两个函数的链接错误,并添加'extern“C”'限定符解决了错误。这怎么可能?
头文件,“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 ++文件,“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 */ }
实现编译没有警告,但是当链接到调用它们的UI代码时,我得到一个正常的
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 *
现在让我困惑的是,只有这两个函数(HandleStart和CheckValid)似乎是用C链接构建的。仅为这两个显式添加“extern'C'”声明解决了链接错误,并且应用程序构建并运行。 在其他一些函数上添加“extern'C'”,例如HandleEnd,会引入一个新的链接错误,因此显然可以正确编译一个。
实现文件永远不会被修改,只有原型。
答案 0 :(得分:1)
函数名称是否与标题中声明的名称冲突?
如果给函数命名不同,你会遇到同样的问题吗?
答案 1 :(得分:1)
错误表明您的实现文件或标头没有任何问题(由实现文件使用) - 链接错误强烈暗示实际生成的函数是使用c ++链接生成的 - 它的UI文件错误地查找C-Linkage版本的功能。修补标题中的定义是修补您的实现以符合可能不正确的UI需求,而不是相反。
您的UI文件是.m或.c文件,或者,如果您的UI文件是.cpp文件,那么您可以使用以下内容:
// ui.cpp
extern "C" {
#include "some_header.h"
}
当然,如果您的UI文件是.c文件 - 您需要将其更改为cpp,或者使用C-linkage明确定义函数,以便可以从C调用它们。