Google Protocol Buffers Libraries for C

Google Protocol Buffers have become a very popular serialization mechanism for simple to complex/variant data structures. Due to the variation of message formats in a given protocol, the presence and/or lack of fields on an ad-hoc basis makes implementation in the C language somewhat of a challenge.

Three Protocol Buffers Libraries for C

Thanks to the open-source world, a couple of valid options exist, but choosing the right one depends on the complexity of the protocol and memory/performance requirements.

Google Protocol Buffers for C++

The obvious first choice may seem to go right to the source. Google’s Protocol Buffer Compiler supports the generation of a C++ protocol implementation from a .proto specification. Though you are developing in C, and your complier supports C++, you could use the C++ API directly from C, or at least create a C wrapper for the target protocol.

  • Pros: Formally supported by Google, bleeding edge
  • Cons: Well, it’s C++ and does lots of dynamic memory allocation

Protobuf-C

If you don’t have the option/desire to use C++, protobuf-c provides a full implementation of Google Protocol Buffers spec up to version 2.5.0.

protobuf-c is a pretty solid and full implementation of protocol buffers completely in C. It provides the protobuf-c library for interfacing with an arbitrary generated protocol. It also provides protoc-c, which is an extension to the Google Protocol Buffer compiler for generating C protocol source code from a standard .proto specification.

  • Pros: Full C implementation, configurable memory usage
  • Cons: Provides structural meta-data, but tree iteration is painful; doesn’t yet support v2.6.0

Protobuf-C-Embedded

If you have very strict memory constraints or maybe don’t have the luxury of dynamic-memory allocation, the you might consider using protobuf-embedded-c. It was written specifically for memory constrained (tiny) systems, and is generated into a monolithic library for a given protocol.

  • Pros: Geared for static memory allocation, simpler API, monolithic library
  • Cons: Doesn’t support message nesting

What Does Protocol Buffers v2.6.0 add?

Google recently released version 2.6.0 of the specification, which adds a formal concept for a union type they refer to as a oneof element. This creates a formal way to say a thing is either A or B, but not both. This allows formal polymorphic types in a protocol specification. It also means a smaller maximum memory footprint and less hassle

Additionally, v2.6.0 introduced a formal deprecation method for protocol elements. A decent level of deprecation has existed for a long time, which basically allows new elements added to a protocol to be added, without breaking the API. The receiver of the protocol buffer simply discards unsupported fields. The main problem with this is that protocol elements at a given level must always use a new ID, and old IDs cannot be reused, which can be annoying. In v2.6.0, elements can be formally deprecated, thus alleviating backwards compatibility pains.
 

Conversation
  • Jamie Bliss says:

    I have been using NanoPB for our embedded project. It supports nested messages and reading/writing directly to streams without the use of dynamic memory.

    The downside is that anything complex requires callbacks to handle. Ick!

    NanoPB’s oneof bug is #131.

    • Jaime,

      Thanks for the heads up on NanoPB! It looks like a more complete implementation of proto buffers than protobuf-c-embedded, which I had to bail on due to the lack of support for nested messages… And the fact that it hasn’t had any commit activity since June of 2013.

      BTW, I have figured out how to define a custom allocator for protobuf-c that will unpack messages to a contiguous block of memory, and will fail gracefully if it runs out of memory.

      Greg

  • Comments are closed.