2015-07-01 174 views
1

我做了一些搜索,但我的問題似乎是微不足道的,所以沒有人問。
我有一個混合的C和C++代碼。Xcode的C/C++鏈接器錯誤:undefined symbol

model.h,我有以下聲明:

void free_and_null (char **ptr); 

model.cpp,我有函數體:

void free_and_null (char **ptr) 
{ 
    if (*ptr != NULL) { 
     free (*ptr); 
     *ptr = NULL; 
    } 
} /* END free_and_null */ 

solve.c文件,我有以下幾點:

#include "sort.h" 
..... 
    free_and_null ((char **) &x); 

當我編譯該項目時,它具有下面的鏈接錯誤:

wrap) Undefined symbols for architecture x86_64: "_free_and_null", referenced from:

爲什麼這麼簡單的程序可以有錯誤?我使用Apple LLVM 6.0作爲編譯器。任何輸入是高度讚賞。

回答

4

您需要告訴C++編譯器該函數應該具有「C」鏈接,方法是聲明它(在您的C++源文件中)。

extern "C" { 
    void free_and_null (char **ptr); 
} 

C++編譯器構建用於功能「錯位」的名稱,以便兩個函數具有相同的名稱,但不同參數類型最終具有不同的錯位的名稱;這是必要的,因爲連接器期望所有名稱都是唯一的。因此,在您的示例中由C++編譯器生成的代碼將生成與由C編譯器生成的名稱不同的名稱。 (在英特爾平臺上,C編譯器也會稍微修改名稱,前綴爲下劃線,這就是爲什麼它會抱怨_free_and_null未被發現。)

執行此操作的一種常見方法是創建一個使用預處理器宏檢測的頭文件語言。它不是完全便攜的,但它應該在你的情況下工作:

// File model.h 
// This will not work with all C++ compilers, but it works with clang and gcc 
#ifdef __cplusplus 
extern "C" { 
#endif 

void free_and_null (char **ptr); 
// Other function declarations here 

#ifdef __cplusplus 
} 
#endif 
+0

謝謝你rici!有用!它提出了關於編譯器和鏈接器的褪色內存。但我仍然記不清,在Xcode中,.c文件和.C++文件是用不同的編譯器編譯的? 我是Xcode的新手。我曾經使用MS Visual Studio,這非常方便和有用。但是因爲我喜歡Macbook,所以我將所有的應用軟件都移到了mac os版本上。 Xcode似乎不如MS Visual Studio那麼方便。你能推薦一些IDE在Mac OS上用於C/C++編碼嗎?謝謝! – user43964

+0

@ user43964:它是相同的編譯器套件(clang),但名稱修飾是ABI的一部分,需要對C和C++名稱進行不同的處理。我對窗戶瞭解不多,但如果它不同,它會讓我感到驚訝。也許你的Windows IDE沒有讓你在一個項目中混合使用語言。如果你用C++編譯C代碼,它通常可以正常工作,並且你沒有命名問題。就mac os x而言,我唯一使用的IDE是xcode。 – rici