代码之家  ›  专栏  ›  技术社区  ›  Christoffer

如何用C++链接建立一些未指定链接的C++函数?

  •  2
  • Christoffer  · 技术社区  · 15 年前

    这使我相当困惑。

    我有一个C++文件来实现一组函数,以及一个头文件,为它们定义原型。

    当使用Visual Studio或MingwGCC构建时,我得到了两个函数的链接错误,并添加了一个“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++文件“Apple实现.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”,会引入一个新的链接错误,因此显然可以正确编译一个函数。

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

    2 回复  |  直到 15 年前
        1
  •  1
  •   Chris Becke    15 年前

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

    您的ui文件是.m或.c文件,或者,如果您的ui文件是.cpp文件,您的dome类似于:

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

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

        2
  •  1
  •   David Sykes    15 年前

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

    如果给函数赋予不同的名称,会出现同样的问题吗?