NanoPB: Comment gérer les types scalaires de base en C++
Voir aussi : Version C : Comment gérer les types scalaires de base en C
NanoPB est une implémentation de Protocol Buffers optimisée pour la taille du code, destinée aux systèmes embarqués. Cet article montre comment gérer les types scalaires de base (entiers, flottants, booléens) en C++ avec NanoPB.
Définition Proto
Créez d’abord un simple fichier .proto avec des types scalaires de base :
syntax = "proto3";
package example;
message ScalarMessage {
uint32 uint32_value = 1;
uint64 uint64_value = 2;
int32 int32_value = 3;
int64 int64_value = 4;
float float_value = 5;
bool bool_value = 6;
}Générer le code NanoPB
Générez le code C++ NanoPB en utilisant le générateur nanopb :
protoc --nanopb_out=. scalars.protoCela générera scalars.pb.h et scalars.pb.c.
Exemple C++
Voici un exemple C++ complet qui encode et décode le message :
#include <stdio.h>
#include <string.h>
#include "scalars.pb.h"
#include "pb_encode.h"
#include "pb_decode.h"
int main() {
// Tampon pour le message encodé
uint8_t buffer[128];
size_t message_length;
// --- ENCODAGE ---
example_ScalarMessage message = example_ScalarMessage_init_zero;
// Définir les valeurs des champs
message.uint32_value = 42;
message.uint64_value = 1234567890ULL;
message.int32_value = -100;
message.int64_value = -9876543210LL;
message.float_value = 3.14159f;
message.bool_value = true;
// Créer le flux pour l'encodage
pb_ostream_t ostream = pb_ostream_from_buffer(buffer, sizeof(buffer));
// Encoder le message
if (!pb_encode(&ostream, example_ScalarMessage_fields, &message)) {
printf("Échec de l'encodage : %s\n", PB_GET_ERROR(&ostream));
return 1;
}
message_length = ostream.bytes_written;
printf("Encodé %zu octets\n", message_length);
// Afficher le dump hexadécimal des données encodées
printf("Données encodées : ");
for (size_t i = 0; i < message_length; i++) {
printf("%02x ", buffer[i]);
}
printf("\n");
// --- DÉCODAGE ---
example_ScalarMessage decoded = example_ScalarMessage_init_zero;
// Créer le flux pour le décodage
pb_istream_t istream = pb_istream_from_buffer(buffer, message_length);
// Décoder le message
if (!pb_decode(&istream, example_ScalarMessage_fields, &decoded)) {
printf("Échec du décodage : %s\n", PB_GET_ERROR(&istream));
return 1;
}
// Afficher les valeurs décodées
printf("Valeurs décodées :\n");
printf(" uint32_value : %u\n", decoded.uint32_value);
printf(" uint64_value : %llu\n", (unsigned long long)decoded.uint64_value);
printf(" int32_value : %d\n", decoded.int32_value);
printf(" int64_value : %lld\n", (long long)decoded.int64_value);
printf(" float_value : %f\n", decoded.float_value);
printf(" bool_value : %s\n", decoded.bool_value ? "true" : "false");
return 0;
}Commande de compilation
Compilez l’exemple avec nanopb. NanoPB est généralement utilisé en incluant directement les fichiers sources dans votre projet :
g++ -o scalars_example scalars_example.cpp scalars.pb.c pb_common.c pb_encode.c pb_decode.c -I.Remarque : Les fichiers sources NanoPB (pb_common.c, pb_encode.c, pb_decode.c) doivent être compilés directement avec votre projet. Vous pouvez les obtenir depuis le dépôt GitHub de NanoPB.
Script de test Python
Pour vérifier l’encodage, vous pouvez utiliser la bibliothèque protobuf de Python :
import scalars_pb2
# Lire les données binaires
with open('encoded.bin', 'rb') as f:
data = f.read()
# Décoder
msg = scalars_pb2.ScalarMessage()
msg.ParseFromString(data)
print("Valeurs décodées par Python :")
print(f" uint32_value : {msg.uint32_value}")
print(f" uint64_value : {msg.uint64_value}")
print(f" int32_value : {msg.int32_value}")
print(f" int64_value : {msg.int64_value}")
print(f" float_value : {msg.float_value}")
print(f" bool_value : {msg.bool_value}")Compilez d’abord les définitions protobuf Python :
protoc --python_out=. scalars.protoModifiez ensuite l’exemple C++ pour enregistrer les données encodées dans un fichier :
// Après l'encodage, ajoutez ceci :
FILE *f = fopen("encoded.bin", "wb");
fwrite(buffer, 1, message_length, f);
fclose(f);Points clés
- Utilisez
*_init_zeropour initialiser les messages avec les valeurs par défaut pb_ostream_from_buffercrée un flux de sortie pour l’encodagepb_istream_from_buffercrée un flux d’entrée pour le décodagepb_encodeetpb_decodegèrent l’encodage/décodage effectif- Vérifiez les valeurs de retour et utilisez
PB_GET_ERRORpour la gestion des erreurs
Sortie attendue
Encoded 28 bytes
Encoded data: 08 2a 10 d2 95 89 04 18 9c ff ff ff ff ff ff ff 01 20 c6 ef be ad de 05 2d 15 49 0e 40 30 01
Decoded values:
uint32_value: 42
uint64_value: 1234567890
int32_value: -100
int64_value: -9876543210
float_value: 3.141590
bool_value: truePlus d’articles sur NanoPB
- Types scalaires de base en C
- Types chaîne en C++
- Types chaîne en C
- Types bytes en C++
- Types bytes en C
- Champs optionnels en C++
- Champs optionnels en C
- Champs répétés/tableaux en C++
- Champs répétés/tableaux en C
- Enums en C++
- Enums en C
- Messages imbriqués en C++
- Messages imbriqués en C
- Types oneof/union en C++
- Types oneof/union en C
- Convertisseurs de tableaux personnalisés en C++
- Convertisseurs de tableaux personnalisés en C