Serializar el objeto C ++ para enviar a través de sockets a Python: ¿el mejor enfoque?

Necesito crear una comunicación de red entre dos marcos diferentes, uno escrito enC++ y el otro enPython.

Para intercambiar datos, quiero crear algún tipo de estructura flexible (básicamente una estructura) enC++, que se serializa, se envía a través de sockets aPython y luego deserializado.

¿Cuál es la forma más común de hacer esto? Estoy seguro queBoost podría hacerlo en cualquier lado, ya que hayboost python, pero no quiero hacer explotar demasiado los requisitos del proyecto. Entonces, ¿hay quizás una biblioteca más pequeña o cualquier otra solución elegante, excepto especificar un formato de datos binarios propio?

ACTUALIZAR

Así que aquí hay un ejemplo de cómo usar Googleprotobuf para enviar una estructura de datos desde unC++ script para unPython script víaUDP. Esto se prueba en Mac OS X Mavericks, pero también debería funcionar bien en otros sistemas Unix.

Instalar protobuf

l primer paso es, por supuesto, instalar elprotobuf biblioteca. Solía homebrew para la biblioteca principal ypip para instalar elPython módulos:

brew install protobuf
pip install protobuf

Entonces definí una estructura de datos muy simple usando la proto-sintaxis:

Nombre de archivo: foo.proto

package prototest;

message Foo {
  required int32 id = 1;
  required string bar = 2;
  optional string baz = 3;
}

Este protoarchivo ahora se puede traducir a clases de C ++ y Python a través de:

protoc foo.proto --cpp_out=. --python_out=.

La carpeta ahora debe contener el encabezado C ++ y los archivos fuente y el código Python:

├── foo.pb.cc
├── foo.pb.h
├── foo.proto
└── foo_pb2.py

Veamos el muy básicoC++ código, que está destinado a enviar una instancia defoo a través de la red, utilizando UDP (a localhost en el puerto 5555):

Nombre de archivo: send.cc

#include <sys/socket.h>
#include <arpa/inet.h>

// this is our proto of foo
#include "foo.pb.h"

int main(int argc, char **argv)
{
  struct sockaddr_in addr;

  addr.sin_family = AF_INET;
  inet_aton("127.0.0.1", &addr.sin_addr);
  addr.sin_port = htons(5555);

  // initialise a foo and set some properties
  GOOGLE_PROTOBUF_VERIFY_VERSION;
  prototest::Foo foo;
  foo.set_id(4);
  foo.set_bar("narf");

  // serialise to string, this one is obvious ; )    
  std::string buf;
  foo.SerializeToString(&buf);

  int sock = socket(PF_INET, SOCK_DGRAM, 0);
  sendto(sock, buf.data(), buf.size(), 0, (struct sockaddr *)&addr, sizeof(addr));

  return 0;
}

Lo compilé a través declang++:

clang++ -o send send.cc foo.pb.cc -lprotobuf

Y finalmente, esta es laPython @, que espera los paquetes UDP y los deserializa enfoo. Nuevamente: no hay ningún error de verificación, esto es solo para demostrar la funcionalidad:

Filename: recibir.py

import socket
from foo_pb2 import Foo

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("127.0.0.1", 5555))

foo = Foo()
while True:
    data, addr = sock.recvfrom(1024)
    foo.ParseFromString(data)
    print("Got foo with id={0} and bar={1}".format(foo.id, foo.bar))

Ahora hemos terminado y esta es la estructura de directorio final:

├── foo.pb.cc
├── foo.pb.h
├── foo.proto
├── foo_pb2.py
├── receive.py
├── send
└── send.cc

Para probar el script, simplemente ejecutereceive.py para escuchar paquetes UDP a través de

python receive.py

y mantén tus ojos en la salida cuando ejecutas el C ++ generadosend script:

./send

Respuestas a la pregunta(2)

Su respuesta a la pregunta