2017-04-12 73 views
1

我可以同時使用protobuf的2.6和3.0庫在同一個C++項目,並將它們連接在一起的兩個不同版本的protobuf庫?鏈接在同一個C++項目

+0

沒有,除非它們包含在自己的命名空間的每個100%。 –

回答

1

我對圖書館並不熟悉,但一般情況下沒有,除非每個圖書館都100%包含在它自己的唯一名稱空間中。否則會出現與每個類別,功能等名稱衝突的問題。

1

您不能將兩個不同版本的libprotobuf鏈接到同一程序中。 (在某些操作系統上可能會有這種情況,但是它絕對不能在Linux上使用,在這種情況下,具有相同名稱的聲明會相互覆蓋。可能可以在Windows或Mac上工作,但這可能不是一個好主意依靠這個。)

但是,你不需要這樣做。 libprotobuf 3.x支持「proto3」和「proto2」語法。只要您可以從源代碼重建代碼(包括重新生成.pb.h和.pb.cc文件),即使某些原始文件使用proto2獨佔,您也應該能夠使用3.x版重建所有內容特徵。

0

儘管C++可能不支持將同一符號的多個版本鏈接到單個對象的概念,但它仍可以完成。像ELF或PE這樣的可執行格式支持許多不屬於C++標準的東西。使用符號可見性和部分鏈接,可以使用使用相同符號的兩個不同副本的代碼。

我猜你想鏈接到兩個不同的已編譯的protobuf共享庫。這是行不通的。您必須靜態鏈接至少一個protobuf並自行編譯它。

這將是這個樣子:

// lib1.c 
void test(void) { printf("test version 1\n"); } 

// lib2.c 
void test(void) { printf("test version 2\n"); } 

// uselib1.c 
void test(void); 
void usetest(void) { test(); } 

// main.c 
void test(void); 
void usetest(void); 
int main(void) { usetest(); test(); } 

我們希望從uselib1.c usetest()調用test()這是在lib1.c的版本,而main()應該調用在lib2.c.版本如果我們只是鏈接所有這些在一起,這是行不通的:

$ gcc uselib1.c lib1.c main.c lib2.c 
/tmp/ccqQhm5c.o: In function `test': 
lib2.c:(.text+0x0): multiple definition of `test' 

你不能,如果test()有多個副本。但是我們可以做的只是部分鏈接uselib1和lib1,因爲只有這兩個對象只有一個test()。然後,來自lib1的符號被本地化,以便使用組合的uselib1 + lib1的其他任何內容都不會看到lib1符號。

$ gcc -c -fvisibility=hidden lib1.c 
$ gcc -c uselib1.c 
$ ld -r uselib1.o lib1.o -o combined1.o 
$ objcopy --localize-hidden combined1.o 
$ gcc main.c lib2.c combined1.o 
$ ./a.out 
test version 1 
test version 2 

當編譯LIB1,我用-fvisibility=hidden爲隱藏在LIB1所有符號標記。如果它是一個共享庫,這會有所作爲。作爲一個對象(或者靜態庫),它們仍然可以被其他代碼使用,當「ld -r」將lib1.o和uselib1.o部分鏈接到combined1.o時,它們會被使用。然後objcopy定位所有隱藏的符號。這有使副本內的combined1.o的作用,就像它是一個static函數。當combined1.o,main.c和lib2.c都鏈接時,main.c將使用lib2.c中的test(),就像我們想要的那樣。

當然,在一個項目中使用兩個不同版本的同一個庫是一個噩夢來維護。你會不斷地包含錯誤版本的頭文件並獲取微妙的錯誤。