使用SWIG绑定Google协议缓冲区
我正在写一个Python程序,需要处理很多小而复杂的protobuf编码消息。我尝试使用纯Python编写的协议缓冲区的Python实现,但它的性能真的很糟糕。
所以我在寻找一个解决方案,听说有些人成功了——使用protoc生成C++文件,然后用swig把它们包装成Python模块。问题是我无法得到一个可以工作的Python模块。
当我用
-includeall
选项运行swig时,目的是确保生成的消息类使用的所有Google基础/工具类也能被包装——但swig失败了,抱怨缺少系统包含文件(例如“string”)。我尝试用 -I 标志或复制整个包含目录来解决这个问题,但都没成功。我的环境是Ubuntu 10.04,protobuf 2.2.0,swig 1.3.40,gcc 4.4.3。如果不使用这个选项,我可以为我的消息类生成一个Python模块,但这个模块没什么用:生成的Python消息类缺少Message基类提供的所有函数——尤其是除了一个以外的所有反序列化方法。剩下的那个方法(MergePartialFromCodedStream)无法运行,因为它需要一个类型为CodedInputStream的输入流(这个是protobuf基础设施的一部分,因此没有被swig包装)。
我想知道有没有人有成功让swig在protobuf-C++上工作的例子?
或者,是否有其他解决方案的例子,比如同一页面提到的Python扩展?不过看起来这对我的动态模式来说维护成本很高……
如果这些都不行,我考虑放弃Python,转而使用Groovy——假设Java实现的协议缓冲区会更高效。对此有什么看法吗?
非常感谢!
3 个回答
试着在你的SWIG文件中使用%include来引入你生成的头文件,同时也要明确地引入基类文件(而不是使用includeall)。这样你应该能清楚地告诉SWIG,你想要绑定基类和派生类。
这里是我最终使用的 Greplin fast-python-pb 解决方案的正确链接。这个工具非常好用(至少在Linux系统上),性能提升了100倍。
这个软件还比较年轻,并不是和谷歌的版本完全兼容,特别是在可选字段的空值处理上 - 不过这些差别其实很小。
新的Protobuf版本支持在Python代码中使用快速的C++实现。你只需要设置一个环境变量,叫做PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION,并把它的值设为cpp。