2011-07-27 21 views
3

我正在按照介紹教程http://www.linuxinsight.com/files/alp/alp-ch01-getting-started.pdf使用C++頭文件在簡單C程序中鏈接錯誤

我創建了源文件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 

據我瞭解,這是有點不正確使用的頭文件,但是我真的不知道該怎麼嘗試,因爲我已經完全遵循了這些步驟。

如果有人有一個想法,爲什麼它扔這個錯誤,我將非常感激。

感謝

**更新 下面是三個源文件代碼:

的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); 

此更改允許我鏈接程序,我現在可以運行它。我認爲可能發生的事情是第二次外在壓倒第一次。如果有人對此有所瞭解,我會有興趣知道。

感謝您的協助。

+1

你能提供你自己的文件的代碼? – Pepe

+1

你能告訴我們你用什麼線來編譯它嗎?聽起來像reciprocal.cpp沒有編譯或沒有被鏈接。 –

回答

5

將C和C++代碼混合在一起時,可能會遇到麻煩,因爲這兩種語言有不同的鏈接。也就是說,如果您要破解已編譯的C和C++文件的對象文件,您會發現這些對象文件中的名稱是不同的。

特別是,C++編譯器傾向於使用一種名爲「name mangling」的技術,其中函數名稱與其參數類型的額外信息混合在一起。例如,函數

char foo(int); 

實際上可能的內部名稱

[email protected]@int 

生成的對象文件裏。問題是C代碼沒有這樣做,所以如果你編譯了一個C文件並試圖引用名稱foo,鏈接器就不會找到它,因爲生成的C++文件中函數的名稱是[email protected]@int而不是foo

爲了解決這個問題,C++有一個功能,可以讓你明確地告訴鏈接器不要裂傷的名稱,使生成的代碼看起來像它的目的是爲C程序。要做到這一點,你可以聲明C++函數是這樣的:

extern "C" char foo(int); 

現在,生成的目標文件將在一個方式,是用C代碼所期待的兼容包含名稱foo沒有裝飾。

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

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

希望這會有所幫助!

+0

感謝這導致我通過閱讀此常見問題找到正確的解決方案:http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html –

1

將C++文件鏈接到C文件很困難。 C++「損壞」這個名字,以致可能發生過載。

您可以通過內附的倒數定義,比如防止的是混淆:

extern "C" { 
    reciprocal definition... 
} 

,但如果你這樣做,你可能也僅僅是用C ...

你能做出一個main.cpp文件?

1

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

+0

感謝您的洞察力。 –