Serialize o objeto C ++ para enviar via sockets para Python - a melhor abordage

Preciso criar uma comunicação de rede entre duas estruturas diferentes, uma escrita emC++ e o outro emPython.

Para trocar dados, quero criar algum tipo de estrutura flexível (basicamente uma estrutura) noC++, que é serializado, enviado através de soquetes paraPython e depois desserializado.

Qual é a maneira mais comum de fazer isso? Tenho certeza queBoost poderia fazê-lo em ambos os lados, uma vez que existeboost python, mas não quero exagerar muito nos requisitos do projeto. Então, talvez exista uma biblioteca menor ou qualquer outra solução elegante, exceto a especificação de um próprio formato de dados binários?

ATUALIZAR

Então, aqui está um exemplo de como usar o Googleprotobuf para enviar uma estrutura de dados de umC++ script para umPython script viaUDP. Isso foi testado no Mac OS X Mavericks, mas também deve funcionar bem em outros sistemas Uni

Installing protobuf

O primeiro passo é instalar oprotobuf library. Eu usei homebrew para a biblioteca principal epip para instalar oPython modules:

brew install protobuf
pip install protobuf

Em seguida, defini uma estrutura de dados muito simples usando a proto-sintaxe:

Filename: foo.proto

package prototest;

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

Este proto-arquivo agora pode ser traduzido para as classes C ++ e Python via:

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

A pasta agora deve conter o cabeçalho C ++ e os arquivos de origem e o código Python:

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

Vamos dar uma olhada no muito básicoC++, que serve para enviar uma instância defoo pela rede, usando UDP (para host local na porta 5555):

Nome do arquivo: 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;
}

Eu compilei viaclang++:

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

E finalmente, este é oPythonódigo @, que aguarda pacotes UDP e desserializa-os parafoo. Novamente: nenhuma verificação de erro, apenas para demonstrar a funcionalidade:

Filename: receive.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))

Agora terminamos e esta é a estrutura final do diretório:

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

Para testar o script, basta executarreceive.py para ouvir pacotes UDP via

python receive.py

e fique de olho na saída quando executar o C ++ geradosend roteiro

./send

questionAnswers(2)

yourAnswerToTheQuestion