为什么一些C ++函数与未指定的链接构建与C链接?

时间:2010-05-20 08:40:11

标签: c++ winapi linkage

这让我感到非常困惑。

我有一个实现一组函数的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,会引入一个新的链接错误,因此显然可以正确编译一个。

实现文件永远不会被修改,只有原型。

2 个答案:

答案 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调用它们。