簡體   English   中英

GCC:使用舊的C代碼時鏈接器錯誤

[英]GCC: linker error when working with old C code

使用GCC編譯器時,我遇到了一個神秘的情況。 所以我有以下文件:

//main.cpp

#include "mleak_cpp.h"
int main(int argc, char* argv[])
{
    foo();
    __memory_malloc(10,"hello",5);
return 0;
}

//mleak_cpp.h

......
void foo(void);
void* __memory_malloc(size_t size, const char* file, int line);

//mleak_cpp.cpp

//definitions of the functions;
void foo(void){printf("foo\n");

void* __memory_malloc(size_t size, const char* file, int line){
    printf("%s,%d\n",file,line);
    InitDoubleLinkList();

    void* p = malloc(size);
    if(p == NULL)
    return NULL;

    __DuLinkList* pListNode;
    pListNode = (__DuLinkList*)malloc(sizeof(__DuLinkList));

    pListNode->address = p;
    pListNode->memorysize = size;
    pListNode->file = file;
    pListNode->line = line;
    InsertBlockToList(pListNode);
    return p;
}

出於某種原因,對void foo(void)的調用很好,但是對“ __memory_malloc”的調用因鏈接器錯誤“ undefined reference”等等而失敗。 導致不同行為的兩個函數之間有什么區別?

我嘗試將“ extern C”添加到“ #include”指令,因此main.cpp讀取:

extern "C"{
    #include "mleak_cpp.h"
}

並在函數的聲明之前添加關鍵字“ extern”,這一次對“ foo()”的調用也因相同的錯誤而失敗。

我感謝你們的任何幫助

您將extern "C"放在錯誤的位置。

如果main.c是一個真正的C文件,並且mleak_cpp.cpp是一個真正的C ++函數,則需要在__memory_malloc()的定義之前加上一個extern "C" ,如下所示:

extern "C" void* __memory_malloc(size_t size, const char* file, int line){
    // ...
}

如果將extern "C"放在mleak_cpp.h文件中,則需要對其進行保護:

#ifdef __cplusplus
    extern "C" {
#endif 

    /* ... body of header ... */

#ifdef __cplusplus
     }
#endif

此外,尚不清楚上面的示例中foo為什么起作用,當一個文件調用__foo()而另一個文件定義foo() 我認為還有更多事情要解決,例如您問題中的編輯錯誤。

extern "C"用於C ++,而不是C,它告訴函數名稱不應該被弄亂。 在C代碼中,您永遠都不會看到這一點。 通常,將其放在頭文件中並加以保護,如下所示:

#ifdef __cplusplus
extern "C" {
#endif

/* C and C++ compatible header file body here */

#ifdef __cplusplus
} /* end extern "C" */
#endif

但是,如果以這種方式進行操作,則需要在C和C ++文件中都包含頭文件,以便C ++編譯器知道使用C鏈接。

您可以將extern "C"放在C ++中的函數定義前面,並將其保留在標頭之外,但這僅在您僅在C代碼中包含標頭的情況下有效,因此建議按照我指出的方式進行操作以上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM