10
votes

Serialize Strings, Ints et Floats aux tableaux de caractères pour la mise en réseau sans bibliothèques

Je veux transmettre des données sur le réseau, mais je ne veux pas utiliser de bibliothèques étrangères (standard C / C ++ est OK).

Par exemple: P>

xyz in binary: 
00000000 0000000 00000000 01111011 | 01101000 | 01101001 | 00000000 | 00111111 10011101 01110000 10100100
- big endian repr. of u. int 123 - | - 'h'  - | - 'i'  - | - '\0' - | -   IEEE 754 repr of float 1.23   -


2 commentaires

Tout d'abord, vous n'avez pas réellement déclaré la variable Y nulle part. Est-ce un tableau de caractères? Savez-vous à quel point ces matrices sont grandes, ou sont-elles dynamiques?


Je suis désolé, je ne peux évidemment pas initialiser y avec un littéral à chaîne en guillemets, j'ai réparé cela. C'est 3 octets de taille.


4 Réponses :


0
votes

Quel est votre objectif exactement? Et quels sont exactement les moyens que vous êtes prêt à utiliser?

Si vous voulez simplement obtenir le travail avec un compilateur particulier sur un ordinateur en particulier, la solution la plus rapide et la plus simple, mais aussi la plus sale, c'est utiliser une union. Vous définissez une structure qui contient vos articles en tant que membres et fusionner qu'avec le tableau de caractères. Vous devez dire au compilateur d'emballer les membres très étroitement, quelque chose dans le sens de #pragma Pack (1) et votre problème est résolu. Vous stockez simplement les trois valeurs dans les membres, puis regardez-la comme une matrice de caractères.

Si la machine est petite Endian et que vous avez besoin de gros INTS / flotteurs Endian, vous échangez simplement les caractères pertinents.

Mais il y a au moins une autre douzaine de solutions qui vous viennent à l'esprit si vous avez d'autres objectifs, comme la portabilité, l'ordre d'octets non standard, la taille de (int)! = 4, flottant non stocké dans IEEE format en interne, etc.


1 commentaires

Je souhaite apprendre à sérialiser les fichiers de données primitifs C / C ++ (d'une manière afin que je puisse ajouter une connaissance des structures sérialisées ultérieurement) en C / C ++. Les moyens sont des fonctions C / C ++ acceptées par GCC et les fonctions de bibliothèque C / C ++ standard. Merci, je vais regarder dans les syndicats.



9
votes

Quelque chose comme le code ci-dessous le ferait. Faites attention aux problèmes où la taille de (non signé INT) est différente de différents systèmes, ceux qui vous mèneront. Pour des choses comme ceci, vous ferez mieux d'utiliser des types avec des tailles bien définies, comme Int32_T. Quoi qu'il en soit ... xxx

... et bien sûr, le code de réception ferait quelque chose de similaire, sauf en inversement.


0 commentaires

1
votes

Ce Discussion semble pertinent à votre question, mais Il utilise une API de sérialisation de boost


2 commentaires

Je pense que Boost vous apprendra beaucoup (vous pouvez rechercher la mise en œuvre). Et vous donnera également une solution prête à de nombreux problèmes que vous ne pouviez pas penser vous-même.


Je vais naviguer autour de l'API de sérialisation de Boost en écrivant ceci (dans un autre onglet XD), mais cela semble survenir pour ce que je veux faire. Essayer de dissiper de manière programmative ...



19
votes

AH, vous souhaitez sérialiser les types de données primitifs! En principe, il y a deux approches: le premier est que vous venez de saisir la représentation binaire interne en mémoire des données que vous souhaitez sérialiser, réinterprétez-la en tant que caractère et utilisez-la comme la représentation:

donc Si vous avez un:

double d;

Vous prenez l'adresse de cela, réinterpréter ce pointeur comme un pointeur sur le caractère, puis utilisez ces caractères: xxx

Ceci fonctionne avec toutes les données primitives avec toutes les données primitives les types. Le principal problème ici est que la représentation de Binray est dépendante de la mise en œuvre (principalement dépendante du processeur). (Et vous rencontrez des bugs subtils lorsque vous essayez de faire cela avec IEEE NANS ...).

Au total, cette approche n'est pas portable du tout, car vous n'avez aucun contrôle du tout sur la représentation de vos données.

La deuxième approche est, d'utiliser une représentation de niveau supérieur, que vous avez vous-même sous contrôle. Si la performance n'est pas un problème, vous pouvez utiliser STD :: strtstream et les >> et << opérateurs pour diffuser des variables de type C primitif C dans STD :: Strings. C'est lent mais facile à lire et à déboguer, et très portable sur le dessus.


4 commentaires

+1 pour mettre en évidence les problèmes et ajouter un rembourrage non défini. Et je vais mordre la bate :), quels sont les bogues subtils avec IEEE NANS dans ce scénario? Merci..


Il y a des nans de signalisation et des nans non signalés. Lorsque vous travaillez avec ces tableaux de caractères, vous pouvez lire et les écrire facilement. Mais lorsque vous les accédez à des flotteurs, l'acte de les lire peut entraîner le signal de la CPU. Donc, si vous n'êtes pas prudent, vous pouvez vous retrouver avec un programme qui désère sans problème, mais une fois que vous avez touché le flotteur, vous vous retrouvez dans des ennuis. Et comme ce fil porte sur l'apprentissage, je pensais que je pourrais signaler cette zone.


+1, et je ne l'ai pas vu mentionné ici dans ce contexte. Bien que les vendeurs ont tendance à éviter le marshalling, ainsi que des flotteurs sérialisés de tout type, enfin :)


La performance est toujours un problème :) C'est toujours la réponse la plus claire sur ce post, merci!