es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Codificar/decodificar cadenas dentro del tipo byte en nanopb con C.

Tengo un archivo .proto que se ve así:

proto
message ObjValue
{
// ...
optional bytes byteval = 6 [max_size = 256]; // arbitrary structure or message
// ...

Utilizo esta codificación proto para enviar estructuras que cambian. Esta estructura básicamente contiene enteros y cadenas (una matriz de caracteres terminada en nulo).

El remitente envía la estructura haciendo algo como esto:

   // Aquí creo la estructura y la lleno con enteros y cadenas
   struct flow<em>msg *flow</em>msg = malloc(sizeof(struct flow<em>msg));
    flow</em>msg->dst<em>addr        = 1;
    flow</em>msg->src<em>addr        = 2;
    flow</em>msg->src<em>ap</em>name     = strdup(src<em>ap</em>name);

// Aquí guardo la longitud de la estructura y un puntero nulo que apunta a la estructura
struct ser_obj_value *obj_value = malloc(sizeof(struct ser_obj_value));
obj_value->size = sizeof(struct flow_msg) + strlen(src_ap_name) + 1; // +1 porque de '\0'
obj_value->data = flow_msg;

Luego, el receptor recibe el mensaje, lo decodifica usando nanopb y luego:

int
handle_msg(void *f_msg)
{
    struct flow_msg *flow_msg = (struct flow_msg *)f_msg;
}

En ese punto, si intento leer el valor de un entero no hay problema (flow_msg->dst_addr, por ejemplo), pero si quiero leer el valor de la cadena, obtengo un puntero nulo porque el flow_msg->src_ap_name está vacío.

Estoy perdido en cuanto a cómo debería codificar/decodificar correctamente el valor de la cadena… Realmente no sé lo que me falta aquí… ¿Alguna pista?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que podría haber un problema con la forma en que la cadena src_ap_name se está codificando y decodificando. Una posible solución sería usar el tipo bytes en el archivo .proto para representar el valor de la cadena:

    message ObjValue
    {
    // ...
        optional bytes src_ap_name = 6 [max_size = 256]; // arreglo de caracteres terminado en nulo
    // ...
    

    Luego, en el código del remitente, se puede codificar la cadena utilizando su representación de bytes:

    // Aquí creo la estructura y la lleno con enteros y cadenas
    struct flow_msg *flow_msg = malloc(sizeof(struct flow_msg));
    flow_msg->dst_addr        = 1;
    flow_msg->src_addr        = 2;
    flow_msg->src_ap_name     = "ejemplo de cadena";
    
    // Aquí guardo la longitud de la estructura y un puntero void que apunta a la estructura
    struct ser_obj_value *obj_value = malloc(sizeof(struct ser_obj_value));
    obj_value->size = sizeof(struct flow_msg) + strlen(flow_msg->src_ap_name) + 1; // +1 porque hay un '\0'
    obj_value->data = flow_msg;
    
    // Codificar la cadena como bytes
    pb_byte_t *src_ap_name_bytes; // Puntero para almacenar la representación byte de la cadena
    size_t src_ap_name_bytes_size = strlen(flow_msg->src_ap_name) + 1; // +1 porque hay un '\0'
    src_ap_name_bytes = malloc(src_ap_name_bytes_size);
    memcpy(src_ap_name_bytes, flow_msg->src_ap_name, src_ap_name_bytes_size); // Copiar la cadena como bytes
    

    Y en el código del receptor, se pueden decodificar los bytes de src_ap_name en una cadena:

    int manejar_mensaje(void *f_msg)
    {
        struct flow_msg *flow_msg = (struct flow_msg *)f_msg;
    
        // Decodificar los bytes como una cadena
        char *src_ap_name = (char *)flow_msg->src_ap_name;
        printf("Valor de la cadena recibida: %s\n", src_ap_name);
    }
    

    Esto debería asegurar que la cadena src_ap_name se codifique y decodifique correctamente como bytes, y se pueda leer y escribir sin problemas.

Comments are closed.