Je suis en série un paquet sur XDR mais je ne comprends pas comment fournir un vecteur de chaîne. J'ai ici une petite sérialisation/désérialisation entièrement fonctionnante pour un std::vector
de uint64_t
. Voici mon code:XDR série de variables longueur de la chaîne
sérialiseur:
#include <stdio.h>
#include <iostream>
#include <rpc/rpc.h>
#include <vector>
#define MAX_LENGTH_ 100
int main(void)
{
XDR xdr;
xdrstdio_create(&xdr, stdout, XDR_ENCODE);
std::vector<uint64_t> ids; // vector i want to send
ids.push_back(1);
ids.push_back(2);
ids.push_back(3);
// serializing the vector
uint64_t *_ids = &ids[0];
uint32_t size = ids.size();
xdr_array(&xdr,(char**)(&_ids), &size, MAX_LENGTH_,sizeof(uint64_t),(xdrproc_t)xdr_u_long);
return 1;
}
désérialiseur:
#include <stdio.h>
#include <iostream>
#include <rpc/rpc.h>
#include <vector>
#define MAX_LENGTH_ 100
int main(void)
{
XDR xdrs;
xdrstdio_create(&xdrs, stdin, XDR_DECODE);
uint64_t *ids_ = new uint64_t[MAX_LENGTH_];
uint32_t size;
bool status = xdr_array(&xdrs,(char**)(&ids_), &size, MAX_LENGTH_,
sizeof(uint64_t), (xdrproc_t)xdr_u_long);
std::vector<uint64_t> ids(ids_,ids_+size);
for(std::vector<uint64_t>::iterator it = ids.begin(); it != ids.end(); ++it)
{
std::cout << *it <<std::endl;
}
return 1;
}
Le code suivant fonctionne ... en cours d'exécution ./serializer | ./deserializer
i 1 2 3. obtenir Maintenant, je ne sais pas comment gérer avoir à sérialiser std::vector<std::string>
. Une chaîne unique fonctionne bien avec xdr_string.
http://linux.die.net/man/3/xdr_array
Toute aide serait très appréciée!
EDIT:
J'ai essayé ce qui suit: sérialiseur:
#include <stdio.h>
#include <iostream>
#include <rpc/rpc.h>
#include <vector>
#include <algorithm>
#include <cstring>
#define MAX_VECTOR_LENGTH_ 100
#define MAX_STRING_LENGTH_ 50
char *convert(const std::string & s)
{
char *pc = new char[s.size()+1];
std::strcpy(pc, s.c_str());
return pc;
}
int main(void)
{
XDR xdr;
xdrstdio_create(&xdr, stdout, XDR_ENCODE);
std::vector<std::string> messages; // vector i want to send
messages.push_back("this is");
messages.push_back("my string");
messages.push_back("vector test");
// transform the vector to c style
std::vector<char*> messagesCStyle;
std::transform(messages.begin(), messages.end(), std::back_inserter(messagesCStyle), convert);
// serializing the vector
char **_messages = &messagesCStyle[0];
uint32_t size = messages.size();
xdr_array(&xdr,(char**)(&_messages), &size, MAX_VECTOR_LENGTH_ * MAX_STRING_LENGTH_,sizeof(char),(xdrproc_t)xdr_string);
return 1;
}
désérialiseur:
#include <stdio.h>
#include <iostream>
#include <rpc/rpc.h>
#include <vector>
#define MAX_VECTOR_LENGTH_ 100
#define MAX_STRING_LENGTH_ 50
int main(void)
{
XDR xdrs;
xdrstdio_create(&xdrs, stdin, XDR_DECODE);
std::vector<char*> messagesCStyle_;
uint32_t size;
bool status = xdr_array(&xdrs,(char**)(&messagesCStyle_), &size, MAX_VECTOR_LENGTH_,
MAX_STRING_LENGTH_, (xdrproc_t)xdr_string);
for(std::vector<char*>::iterator it = messagesCStyle_.begin(); it != messagesCStyle_.end(); ++it)
{
std::cout << *it <<std::endl;
}
return 1;
}
Je suis assez sûr que le code de la sérialiseur je s pas mieux, mais au moins, il semble fonctionner. Cependant le désérialiseur ne le fait pas !! Je pense que le problème est lié au fait que je ne sais pas combien de mémoire allouer avant d'appeler le xdr_array. De l'aide?
est-ce pas un XDR C seule spec? Ensuite, pour l'utiliser pour std :: string, vous devrez peut-être extraire une chaîne compatible C avec, par exemple, messages [i] .c_str(). Ou utilisez la sérialisation boost pour éviter de recourir à un vieux C. –
Tout le reste de l'eporject utilise XDR donc je dois m'en tenir à lui! J'ai marqué la question en tant que C mais Michael a retiré mon tag .... – Stefano
J'ai mis à jour la question avec un code complet. – Stefano