2010-08-07 52 views
1

假設我有一個C++程序,並且我想從其中的C目標文件中調用函數。約束是我不允許對C源文件進行任何更改。在幾個含有等效簽名功能的C目標文件中鏈接

在這種情況下,我將包括C頭作爲的extern「C」在我的C++文件,調用函數,編譯使用GCC -c C對象,並且將結果傳遞給克++沿實際的C++源代碼。

我想我還要做的是把C-頭的#include名爲命名空間塊內部的C++文件,以保持局部命名空間乾淨(誰知道還有什麼其他花哨的東西有什麼在.h文件中)。

現在如果我需要從兩個C目標文件中調用函數。可以說他們有不同的簽名。但是在對象文件中也有一些重複的功能。如果我試圖同時將兩個對象傳遞給g ++,那麼我的鏈接器在這一點上是否會炸燬?全局相同。

再次:我不允許更改ANY的C源代碼。否則,我只是將.c文件重命名爲.cxx,將其內容和相應標頭的內容封裝在命名空間bla {}內,並將所有內容填入g ++

(是的,C是不是C++的一個子集,如已經在評論中提及了)

+0

如果Carl的建議對你有效,爲什麼不能簡單地用'-x C++'編譯C源代碼?你想要命名空間? – 2010-08-07 16:32:37

+0

由於多重定義,鏈接器是否會繼續繁榮? – nisc 2010-08-07 16:37:17

+0

是的,會的。我錯過了,因爲我沒有看過「假設他們有不同的簽名......」之後的句子...... – 2010-08-07 16:55:12

回答

2

你的最後一段有一個很好的解決方案 - 爲什麼不把C++的文件是這樣的:

namespace c_namespace_1 { 
    #include "CFile1.c" 
} 

namespace c_namespace_2 { 
    #include "CFile2.c" 
} 

依此類推....那麼你可以編譯這個文件爲C++而不必修改原始的源代碼。

+1

可能這些文件不是C++;他們是C. ** C不是C++ **的子集,並且沒有理由期望C源文件能夠編譯爲C++代碼。 – 2010-08-07 16:15:58

+0

令人驚歎和擔心,同時我無法自己想出。會嘗試。謝謝。 – nisc 2010-08-07 16:18:33

+0

@R .:在這種情況下,它們是C++的子集。但總是歡迎更好的解決方案。 – nisc 2010-08-07 16:19:20

1

您可以將C可執行代碼作爲單獨的二進制數據文件引入,並處理自己的函數指針轉換 - 基本上爲鏈接器完成它的工作。如果二進制文件不能正常工作,請獲取C文件的彙編程序輸出,並將其封裝在類似於上述名稱空間建議的函數中。

0

如何編譯每個C子系統到它自己的LIB文件,然後編譯一個單獨的C++ LIB文件,其中包括適當的C LIB,並提供包裝的函數在其.LIB

即調用只有C功能:

file1.c => file1.lib 
file2.c => file2.lib 

Wrapper1.cpp + file1.lib => Wrapper1.lib 
Wrapper2.cpp + file2.lib => Wrapper2.lib 

Application.cpp + Wrapper1.lib + wrapper2.lib => Application.exe 

注意,這關我的頭頂,我不知道如果鏈接器仍然會去轟

當然,你可以編譯Wrapper1和Wrapper2到DLL的,而不是庫的,並且這將確保鏈接不去繁榮!

0

這很不好意思,但一種解決方案是通過宏來重命名有問題的函數,這樣就鏈接器而言它們有不同的名稱。

舉例來說,如果你有太多的功能稱爲foo,其中一個接受一個int和其他工作都需要一個double,在文件IntFoo.c和DoubleFoo.c,你可以編譯他們是這樣的:

cc -Dfoo=IntFoo -o IntFoo.o IntFoo.c 
cc -Dfoo=DoubleFoo -o DoubleFoo.o DoubleFoo.c 

然後在C++中,你可以這樣做:

#define foo IntFoo 
extern "C" { 
    #include "IntFoo.h" 
} 

#define foo DoubleFoo 
extern "C" { 
    #include "DoubleFoo.h" 
} 

#undef foo 

這裏有很多需要注意的地方:你必須確保符號foo僅作爲你想要的功能的名稱,就可以去en確保您在使用符號foo的每個地方都適當地定義宏。如果有重複的符號,您也必須爲這些宏定義宏。

這可能是一個更好的解決方案來修復C文件。