簡體   English   中英

使用C ++標頭在簡單C程序中鏈接錯誤

[英]Linking error in simple C program using a C++ header

我正在關注一個介紹教程http://www.linuxinsight.com/files/alp/alp-ch01-getting-started.pdf

我創建了源文件main.c,reciprocal.cpp和reciprocal.hpp。 我已經能夠成功編譯這些文件。 當我去鏈接它們時出現問題,我收到以下錯誤消息:

main.o: In function `main':
main.c:(.text+0x30): undefined reference to `reciprocal'
collect2: ld returned 1 exit status

我認為這是不正確地使用頭文件,但我真的不知道該嘗試什么,因為我已經非常徹底地遵循了這些步驟。

如果有人知道為什么它會拋出那個錯誤我會非常感激。

謝謝

** UPDATE以下是三個源文件的代碼:

main.c中

#include <stdio.h>
#include "reciprocal.hpp"

int main (int argc, char **argv) {
    int i;
    i = atoi(argv[1]);
    printf("The reciprocal of %d is %g\n", i, reciprocal(i));

    return 0;
}

reciprocal.cpp

#include <cassert>
#include "reciprocal.hpp"

double reciprocal(int i) {
    assert(i != 0);
    return 1.0/i;
}

reciprocal.hpp

#ifdef __cplusplus
extern "C" {
#endif

double reciprocal(int i);

#ifdef __cplusplus
}
#endif

我實際上已經修改了自最初發布以來的reciprocal.hpp。 我做的唯一更改是從函數簽名中刪除extern關鍵字。 它以前讀過

extern double reciprocal(int i);

這個更改允許我鏈接程序,我現在可以運行它。 我認為可能發生的事情是,第二個外部正在壓倒第一個外部。 如果有人對此有任何見解,我會有興趣知道。

感謝大家的幫助。

將C和C ++代碼混合在一起時,可能會遇到麻煩,因為這兩種語言具有不同的鏈接 也就是說,如果你要打開已編譯的C和C ++文件的目標文件,你會發現這些目標文件中的名稱是不同的。

特別是,C ++編譯器傾向於使用一種稱為“名稱修改”的技術,其中函數名稱與關於其參數類型的額外信息混合在一起。 例如,一個函數

char foo(int);

可能實際上有內部名稱

char@foo@int

在生成的目標文件中。 問題是C代碼沒有這樣做,所以如果你編譯了一個C文件並試圖引用名稱foo ,鏈接器就找不到它,因為生成的C ++文件中的函數名是char@foo@int而不是foo

為了解決這個問題,C ++有一個功能,允許您明確地告訴鏈接器不要破壞名稱,並使生成的代碼看起來像是用於C程序。 為此,您可以聲明C ++函數,如下所示:

extern "C" char foo(int);

現在,生成的目標文件將包含名稱foo而不是裝飾,其方式與C代碼所期望的方式兼容。

要解決您的問題,請嘗試將其中一個extern "C"聲明添加到定義reciprocal C ++源文件中。

注意:如果你有一個混合C和C ++代碼的項目,你應該總是main函數編譯為C ++代碼。 C ++將額外的初始化和清理代碼引入到C代碼中不存在的可執行文件中。 如果將main編譯為C代碼,則可能無法將此額外邏輯添加到程序中,因此您可能會在運行時遇到無法解釋的崩潰。

希望這可以幫助!

將C ++文件鏈接到C文件很困難。 C ++“破壞”名稱,以便可以發生重載。

您可以通過包含這樣的倒數定義來防止錯位:

extern "C" {
   reciprocal definition...
}

但如果你這樣做,你也可以用C語寫它...

你能制作一個main.cpp文件嗎?

看起來你的reciprocal.hpp的內容是無效的,可能是#ifdef行中的拼寫錯誤, __cplusplus拼寫正確(應該有兩個下划線)?

暫無
暫無

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

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