如何处理包名与消息名重复的多个.proto文件(无需修改原文件)
解决Protobuf重复命名空间符号冲突的方案
现有两个分属不同服务的.proto文件(如foo.proto和bar.proto),二者均使用包名internal且都定义了ToService消息。在同一程序中调用这两个协议时,出现重复符号链接错误:两者都定义了internal::ToService::~ToService及internal::命名空间下的其他符号。希望尽量不修改原.proto文件,指定protoc在不同命名空间下生成代码。
核心解决方案(C++场景)
从错误符号判断为C++编译场景,可通过protoc命令行参数分别为两个.proto文件指定不同的目标命名空间,无需修改原文件:
- 编译
foo.proto时,用--cpp_opt=namespace=foo_internal参数将生成代码的命名空间替换为foo_internal:protoc --cpp_out=. --cpp_opt=namespace=foo_internal foo.proto - 编译
bar.proto时,用--cpp_opt=namespace=bar_internal参数将生成代码的命名空间替换为bar_internal:protoc --cpp_out=. --cpp_opt=namespace=bar_internal bar.proto
生成的foo.pb.h和bar.pb.h中,原internal命名空间会被替换为指定的新命名空间,链接时即可避免重复符号冲突。
其他语言适配方案
如果使用其他编程语言,也有对应的protoc参数调整生成代码的包/命名空间:
- Go语言:通过包映射参数分别指定不同的Go包路径:
protoc --go_out=. --go_opt=Mfoo.proto=your/project/foo/internal foo.proto protoc --go_out=. --go_opt=Mbar.proto=your/project/bar/internal bar.proto - Java语言:通过参数指定不同的Java包名:
protoc --java_out=. --java_opt=package=com.foo.internal foo.proto protoc --java_out=. --java_opt=package=com.bar.internal bar.proto
内容的提问来源于stack exchange,提问作者mort
相关产品推荐
相关产品推荐

