为什么有些 C++具有未指定链接的函数使用 C 链接构建?

发布于 2024-09-02 02:40:13 字数 1468 浏览 3 评论 0原文

这是让我相当困惑的事情。

我有一个实现一组函数的 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'”声明解决了链接错误,并且应用程序构建并运行。 在其他一些函数(例如 HandleEnd)上添加“extern 'C'”会引入一个新的链接错误,因此显然可以正确编译。

实现文件在任何情况下都不会被修改,只有原型。

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 prototypes 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖不如嘢 2024-09-09 02:40:13

该错误表明您的实现文件或标头(如实现文件所使用的)没有任何问题 - 链接错误强烈表明实际生成的函数是通过 C++ 链接生成的 - 它的 UI 文件错误地查找 C-Linkage函数的版本。修补标头中的定义就是修补您的实现,以符合 UI 可能不正确的要求,而不是相反。

您的 UI 文件是 .m 或 .c 文件,或者,如果您的 UI 文件是 .cpp 文件,您的圆顶类似:

// ui.cpp
extern "C" {
#include "some_header.h"
}

当然,如果您的 UI 文件是 .c 文件 - 您需要将其更改为cpp,或使用 C 链接显式定义函数,以便可以从 C 调用它们。

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.

橘虞初梦 2024-09-09 02:40:13

函数名称是否会与标头中声明的名称冲突?

如果给函数赋予不同的名称,是否会遇到同样的问题?

Could the function names conflict with names declared in a header?

Do you get the same problem if you give the functions different names?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文