我可以在同一个c ++项目中使用protobuf 2.6和3.0库并将它们链接在一起吗?
答案 0 :(得分:4)
您无法将两个不同版本的libprotobuf链接到同一个程序中。 (这可能在某些操作系统上,但它绝对不会在Linux上运行,其中具有相同名称的声明会相互覆盖。可能可以在Windows或Mac上运行,但是依靠这个可能不是一个好主意。)
但是,您不需要这样做。 libprotobuf 3.x支持" proto3"和" proto2"句法。只要您可以从源代码重建代码(包括重新生成.pb.h和.pb.cc文件),您就应该可以使用版本3.x重建所有内容,即使某些原型文件使用proto2-exclusive特征
答案 1 :(得分:0)
我不熟悉这个库,但除非每个库100%包含在它自己独特的命名空间中,否则通常都不会。否则每个类,函数等都会有名称冲突。
答案 2 :(得分: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()
调用lib1.c中的test()
版本,而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本地化所有隐藏的符号。这样做的结果是将test()
复制到combined1.o就像是static
函数一样。当combined1.o,main.c和lib2.c全部链接时,main.c将使用lib2.c中的test()
,就像我们想要的那样。
当然,在一个项目中使用同一个库的两个不同版本是一个难以维护的噩梦。你将经常包含错误版本的标题并获得微妙的错误。