OVH Cloud OVH Cloud

void* en string

8 réponses
Avatar
Michael
Bonsoir à tous,

je suis en train de créer une classe permettant de communiquer avec un port
COM, et je me heurte à un petit souci.

Voici la fonction permettant de récupérer les données du port COM:

//-------------------------------------------------------------------------
--
void COM_IO::GetData(std::string & data)
{
char * d = new char[data.length()];

DWORD o;
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM");

data = d;

delete[] d;
}

En fait, ce que j'aimerais éviter, c'est une fonction de ce type:

void COM_IO::GetData(char * data, unsigned int dataSize)
{

}

L'utilisateur utilisera la classe comme suit:

std::string p;
p.resize(17);

COM_IO * c = new COM_IO(1);
c->InitForRead();

while (1)
{
c->GetData(p);
if (stop)
break;
}

Mais actuellement, la string p retournée n'est absolument pas bonne...

Où est-ce que ça cloche à votre avis?

Merci d'avance

Mike

8 réponses

Avatar
Fabien LE LEZ
On 03 Oct 2006 17:33:32 GMT, Michael <michael.at.gmail.dot.com>:

void COM_IO::GetData(std::string & data)
{
char * d = new char[data.length()];

DWORD o;
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM");

data = d;


Et s'il y a un '' qui traîne là-dedans, il coupera la chaîne.

Je verrais plutôt un truc de ce goût-là :

std::string GetData (size_t taille)
{
std::vector<char> buf (taille);
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

return std::string (buf.begin(), buf.end());
}


Si tu veux vraiment garder la même convention d'appel (bancale AMHA,
m'enfin bon...) :

void GetData (std::string& dest) // bof...
{
size_t const taille= buf.size();
std::vector<char> buf (taille);
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

dest= std::string (buf.begin(), buf.end());
}

Avatar
loufoque

p.resize(17);


reserve n'a aucune influence sur length

Avatar
James Kanze
Fabien LE LEZ wrote:
On 03 Oct 2006 17:33:32 GMT, Michael <michael.at.gmail.dot.com>:

void COM_IO::GetData(std::string & data)
{
char * d = new char[data.length()];

DWORD o;
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM" );

data = d;


Et s'il y a un '' qui traîne là-dedans, il coupera la chaîne.


Et s'il n'y en a pas, ça risque d'être encore plus amusant, non :-)?
(Pense à comment std::string cherche la longueur quand tu ne lui
donne pas explicitement.)

Je ne connais pas la fonction ReadFile, mais il doit bien être
possible d'en récouperer la longueur lue quelque part. Puis :

data.assign( d, longueurLue ) ;

Je verrais plutôt un truc de ce goût-là :

std::string GetData (size_t taille)
{
std::vector<char> buf (taille);
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))


C'est quoi, d ?

Pendant que j'y suis, je ne vois pas de o ni de data non plus.
L'idée d'utiliser un std::vector< char > me semble bonne, mais

std::vector< char > buf( taille ) ;
ssize_t lu = read( hPortCOM, &buf[ 0 ], buf.size() ) ;
if ( lu == -1 ) {
throw Exception( "Erreur de lecture" ) ;
}
return std::string( buf.begin(), buf.begin() + lu ) ;

. Convertir le read en ReadFile, et ça doit faire l'affaire sous
Windows aussi.)

throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

return std::string (buf.begin(), buf.end());
}

Si tu veux vraiment garder la même convention d'appel (bancale AMHA,
m'enfin bon...) :


Je doute que ce soit le cas ici, mais ça m'est déjà arrivé de
passer un Container& plutôt que de renvoyer un Container pour
des motifs de performance. (Dans mon cas, le Container, c'était
un pré-STL équivalent à std::list. Avec en moyen 60.000
entrées.)

void GetData (std::string& dest) // bof...
{
size_t const taille= buf.size();
std::vector<char> buf (taille);


J'adore :-). On démande à l'objet qui n'existe pas sa taille
pour qu'on puisse lui dire d'avoir cette taille.

(Manifestement, il te manque du sommeil, ou du café, ou quelque
chose. Mais il faut avouer, le résultat ici pose une question
métaphysique assez intéressante.)

if (!ReadFile(hPortCOM, d, data.length(), &o , 0))


Et on continue. Ayant soigneusement construit le buf avec la
taille qu'il a dit qu'il a, on ne s'en sert plus, lui préférant
des symboles jamais vus avant. (Je suis en train de supposer que
hPortCOM est une variable globale, vue que Michael ne l'a pas
déclarée non plus. Et je suis sûr qu'avec un peu plus de
sommeil, tu lui aurais indiqué que ce n'est pas une bonne idée
non plus.)

throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

dest= std::string (buf.begin(), buf.end());


Au moins on sait ce que la chaîne va contenir : que des char()
(c-à-d des '') :-). (Et je suppose que c'est le sommeil aussi
qui t'a fait utiliser l'opérateur d'affectation, plutôt que la
fonction membre assign().)

}



Avatar
James Kanze
Fabien LE LEZ wrote:
On 03 Oct 2006 17:33:32 GMT, Michael <michael.at.gmail.dot.com>:

void COM_IO::GetData(std::string & data)
{
char * d = new char[data.length()];

DWORD o;
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))
throw Exception("Impossible d'envoyer la séquence au port COM" );

data = d;


Et s'il y a un '' qui traîne là-dedans, il coupera la chaîne.


Et s'il n'y en a pas, ça risque d'être encore plus amusant, non :-)?
(Pense à comment std::string cherche la longueur quand tu ne lui
donne pas explicitement.)

Je ne connais pas la fonction ReadFile, mais il doit bien être
possible d'en récouperer la longueur lue quelque part. Puis :

data.assign( d, longueurLue ) ;

Je verrais plutôt un truc de ce goût-là :

std::string GetData (size_t taille)
{
std::vector<char> buf (taille);
if (!ReadFile(hPortCOM, d, data.length(), &o , 0))


C'est quoi, d ?

Pendant que j'y suis, je ne vois pas de o ni de data non plus.
L'idée d'utiliser un std::vector< char > me semble bonne, mais

std::vector< char > buf( taille ) ;
ssize_t lu = read( hPortCOM, &buf[ 0 ], buf.size() ) ;
if ( lu == -1 ) {
throw Exception( "Erreur de lecture" ) ;
}
return std::string( buf.begin(), buf.begin() + lu ) ;

. Convertir le read en ReadFile, et ça doit faire l'affaire sous
Windows aussi.)

throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

return std::string (buf.begin(), buf.end());
}

Si tu veux vraiment garder la même convention d'appel (bancale AMHA,
m'enfin bon...) :


Je doute que ce soit le cas ici, mais ça m'est déjà arrivé de
passer un Container& plutôt que de renvoyer un Container pour
des motifs de performance. (Dans mon cas, le Container, c'était
un pré-STL équivalent à std::list. Avec en moyen 60.000
entrées.)

void GetData (std::string& dest) // bof...
{
size_t const taille= buf.size();
std::vector<char> buf (taille);


J'adore :-). On démande à l'objet qui n'existe pas sa taille
pour qu'on puisse lui dire d'avoir cette taille.

(Manifestement, il te manque du sommeil, ou du café, ou quelque
chose. Mais il faut avouer, le résultat ici pose une question
métaphysique assez intéressante.)

if (!ReadFile(hPortCOM, d, data.length(), &o , 0))


Et on continue. Ayant soigneusement construit le buf avec la
taille qu'il a dit qu'il a, on ne s'en sert plus, lui préférant
des symboles jamais vus avant. (Je suis en train de supposer que
hPortCOM est une variable globale, vue que Michael ne l'a pas
déclarée non plus. Et je suis sûr qu'avec un peu plus de
sommeil, tu lui aurais indiqué que ce n'est pas une bonne idée
non plus.)

throw Exception("Impossible d'envoyer la séquence au port COM");
// T'es sûr que c'est le bon message ?

dest= std::string (buf.begin(), buf.end());


Au moins on sait ce que la chaîne va contenir : que des char()
(c-à-d des '') :-). (Et je suppose que c'est le sommeil aussi
qui t'a fait utiliser l'opérateur d'affectation, plutôt que la
fonction membre assign().)

}



Avatar
Franck Branjonneau
loufoque écrivait:


p.resize(17);


reserve n'a aucune influence sur length


Et resize ?

--
Franck Branjonneau


Avatar
Fabien LE LEZ
On 3 Oct 2006 13:00:58 -0700, "James Kanze" :

(Manifestement, il te manque du sommeil, ou du café, ou quelque
chose.


Yep. Depuis hier matin, j'évite au maximum de faire quoi que ce soit
d'important, car je ne fais que des conneries :-(

Avatar
Fabien LE LEZ
On 3 Oct 2006 13:06:42 -0700, "James Kanze" :

(Manifestement, il te manque du sommeil,


C'est plutôt l'inverse : j'ai dormi dix-huit heures de rang, et
depuis, je n'arrive pas à me réveiller.

ou du café, ou quelque chose.


J'en suis arrivé à voir double : je vois le même message deux fois
(<news: et
<news:).

Avatar
Michael
Et bien, merci à tous les deux ;)