protoc protobuf google c++ dynamic protocol-buffers

c++ - google - ¿Cómo construir dinámicamente un nuevo protobuf a partir de un conjunto de descriptores ya definidos?



protobuf windows (3)

¿Qué hay de serializar todos los mensajes en cadenas y hacer que el mensaje maestro sea una secuencia de cadenas (de bytes), a la

message MessageSet { required FileDescriptorSet proto_files = 1; repeated bytes serialized_sub_message = 2; }

En mi servidor, recibimos mensajes autodescritos (como se define here ... que por cierto no fue tan fácil ya que no hay ningún "buen" ejemplo de esto en c ++).

En este punto, no tengo problemas para crear mensajes de estos autodescritos. Puedo tomar el FileDescriptorSet, revisar FileDescriptorProto y agregar cada uno a DescriptorPool (usando BuildFile , que también me proporciona todos los FileDescriptor definidos).

Desde aquí puedo crear cualquiera de los mensajes que se definieron en FileDescriptorSet con DynamicMessageFactory instanciado con el DP y llamando a GetPrototype (que es muy fácil de hacer ya que SelfDescribedMessage requería los mensajes full_name () y así podemos llamar al método FindMessageTypeByName de el DP, dándonos el Prototipo de mensaje adecuadamente codificado).

La pregunta es cómo puedo tomar cada Descriptor o mensaje ya definido y construir dinámicamente un mensaje ''maestro'' que contenga todos los mensajes definidos como mensajes anidados. Esto se usaría principalmente para guardar el estado actual de los mensajes. Actualmente estamos manejando esto simplemente instalando un tipo de cada mensaje en el servidor (para mantener un estado central en diferentes programas). Pero cuando queremos ''guardar'' el estado actual, nos vemos obligados a transmitirlos al disco como se define here . Se transmiten un mensaje a la vez (con un prefijo de tamaño). Nos gustaría tener UN MENSAJE (uno para gobernarlos a todos) en lugar de un flujo constante de mensajes separados. Esto se puede usar para otras cosas una vez que se resuelve (estado compartido basado en red con serialización optimizada y fácil)

Dado que ya tenemos los descriptores entrecruzados y definidos, uno pensaría que habría una manera fácil de construir mensajes ''nuevos'' a partir de aquellos ya definidos. Hasta ahora, la solución nos ha aludido. Hemos intentado crear nuestro propio DescriptorProto y agregar nuevos campos del tipo de nuestros Descriptores ya definidos, pero nos hemos perdido (aún no nos hemos sumergido en este). También hemos analizado la posibilidad de agregarlos como extensiones (se desconoce en este momento cómo hacerlo). ¿Necesitamos crear nuestro propio DescriptorDatabase (también desconocido en este momento cómo hacerlo)?

¿Alguna idea?

Fuente de ejemplo vinculada en BitBucket.

Con suerte, esta explicación ayudará.

Estoy intentando construir dinámicamente un Mensaje a partir de un conjunto de Mensajes ya definidos. El conjunto de mensajes ya definidos se crea utilizando el método "autodescrito" explicado (brevemente) en el tutorial oficial de c ++ protobuf (es decir, estos mensajes no están disponibles en forma compilada). Este mensaje recién definido deberá crearse en tiempo de ejecución.

He intentado utilizar los descriptores directos para cada mensaje e intenté crear un FileDescriptorProto. He intentado mirar los métodos DatabaseDescriptor. Ambos sin suerte. Actualmente, intenta agregar estos mensajes definidos como una extensión a otro mensaje (incluso en el momento de la compilación, esos mensajes definidos, y su ''conjunto de descriptores'' no se clasificaron como extendiendo nada), que es donde comienza el código de ejemplo.


Pude resolver este problema creando dinámicamente un archivo .proto y cargándolo con un Importer .

El único requisito es que cada cliente envíe a través de su archivo proto (solo se necesita en init ... no durante la ejecución completa). El servidor luego guarda cada archivo proto en un directorio temporal. Una alternativa, si es posible, es simplemente apuntar el servidor a una ubicación central que contenga todos los archivos proto necesarios.

Esto se hizo usando primero un DiskSourceTree para mapear las ubicaciones reales de las rutas en las virtuales del programa. Luego construyendo el archivo .proto para importar cada archivo proto enviado a través Y definir un campo opcional en un ''mensaje maestro''.

Después de que master.proto se haya guardado en el disco, lo master.proto con el importador. Ahora, usando Importers DescriptorPool y DynamicMessageFactory, puedo generar de manera confiable todo el mensaje en un solo mensaje. Voy a poner un ejemplo de lo que estoy describiendo más tarde esta noche o mañana.

Si alguien tiene alguna sugerencia sobre cómo mejorar este proceso o cómo hacerlo diferente, dígalo.

Dejaré esta pregunta sin respuesta hasta que la recompensa esté a punto de caducar solo en caso de que alguien más tenga una mejor solución.


necesitas un protobuf::DynamicMessageFactory :

{ using namespace google; protobuf::DynamicMessageFactory dmf; protobuf::Message* actual_msg = dmf.GetPrototype(some_desc)->New(); const protobuf::Reflection* refl = actual_msg->GetReflection(); const protobuf::FieldDescriptor* fd = trip_desc->FindFieldByName("someField"); refl->SetString(actual_msg, fd, "whee"); ... cout << actual_msg->DebugString() << endl; }