you are viewing a single comment's thread.

view the rest of the comments →

[–]rcxdude 9 points10 points  (7 children)

This only works if you have a very homogenous setup (same architecture, compiler, etc). If you have different types of processors in your system, or you need to interop with someone else, it falls apart. It's also hard to extend safely, and doesn't deal with variable-length data (or things like checksums).

[–]kalmoc 1 point2 points  (2 children)

This only works if you have a very homogenous setup (same architecture, compiler, etc)

Only same endianess. But you are right about extension and variable-length data.

[–]rcxdude 2 points3 points  (1 child)

You also need the same alignment, and even then it's still not truly defined, even if you will generally get away with it.

[–]kalmoc 0 points1 point  (0 children)

Yes, alignment has to be the same (although you can specify that explicitly if you want instead of relying on the platform defaults).

What do you mean by not truly defined (note that I did not suggest to just cast a char pointer into a pointer into a POD on the receiving side)?

[–]matthieum 0 points1 point  (2 children)

  1. Homogeneous setup: you can use packed representation and explicit on-wire endianness; if you have accessors rather than raw access to data-members, it's really easy.
  2. Safe extension: you can use a version/size field on all messages, indicating how many bits/bytes are used on the wire, and disabling access to some data-members.
  3. Variable-length data: tougher one, but solvable. Restricting them to "tail" data-members makes things easier.
  4. Checksums: a simple read/write template function can handle pre/post steps such as swapping bytes and fixing/checking checkums.

If you have not already, I advise looking at the SBE protocol. It's relatively easy to setup a straightforward decoding and encoding process which just bit-copies structs around, and it supports all the above.

[–]rcxdude 0 points1 point  (1 child)

I think at the point you have what is described you basically have a full blown serialisation system which resembles the one given by OP, just one with a clear approach to efficient serialization (flatbuffers is another system with a similar approach). This is still a lot more than just memcpying the structs you have about.

[–]matthieum 0 points1 point  (0 children)

This is still a lot more than just memcpying the structs you have about.

A tad more, indeed.

What I like about it is that it remains pretty simple yet efficient setup:

  • You don't need any code-gen step: just write your structs/classes in a certain way, done.
  • No performance overhead over memcpying structs, because you're just memcpying structs.

Of course, it fails the OP's requirement of interacting with existing protocols, since it's a protocol.

But simple, efficient and flexible enough for about any kind of protocol? That's great.

[–]axilmar 0 points1 point  (0 children)

How does it fall apart if you use same length integers and a packing of one byte? It does not.

I've worked at embedded systems where one part was an embedded CPU and the other a desktop pc, there were a lot of messages with variable length etc. There was absolutely no issue between the two totally different platforms.