C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Des char* en pagaille

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Fabien LE LEZ
Guest





PostPosted: Thu Sep 08, 2005 4:50 pm    Post subject: Des char* en pagaille Reply with quote



Bonjour,

Une fonction de l'API Windows s'écrit à peu près ainsi :

size_t GetModuleFileName
(HMODULE hModule,
char* buffer_nom_fichier,
size_t taille_du_buffer);

La valeur de retour est le nombre d'octets copiés dans le buffer.
Je considère que si cette valeur de retour est égale à
taille_du_buffer, c'est que le buffer est trop petit, il faut
l'augmenter.

J'ai donc écrit :

std::string GetModuleFileName (HMODULE module)
{
size_t taille_buf= 256;
for(;Wink
{
std::vector<char> buf (taille_buf);
DWORD resultat= GetModuleFileName (module, &buf[0], buf.size());
if (resultat < taille_buf)
{
return std::string (buf.begin(), buf.begin()+resultat);
}
taille_buf*=2;
}
}

Le style serait à améliorer, et je n'ai tenté aucune optimisation,
mais le principe est là : si le buffer est assez grand, je renvoie la
réponse ; sinon, je l'augmente et je réessaie.

Maintenant, j'aimerais savoir s'il est possible de rendre ce code plus
générique, afin de ne pas tout réécrire pour une fonction

size_t AutreFonction
(char* buffer_nom_fichier, size_t taille_du_buffer,
double machin, int truc);


Et j'avoue que je sèche un peu. Les seules solutions que j'entrevois
seraient nettement plus compliquées à utiliser que de tout réécrire à
chaque fois.

Donc, si quelqu'un a une solution simple et élégante...
Merci d'avance !

Back to top
Stan
Guest





PostPosted: Thu Sep 08, 2005 5:01 pm    Post subject: Re: Des char* en pagaille Reply with quote




"Fabien LE LEZ" <gramster (AT) gramster (DOT) com> a écrit dans le message de news:
[email]edq0i1lllqejh9vsjdu7ildq9crkn2aht6 (AT) 4ax (DOT) com[/email]...
Quote:
Bonjour,

[...]


Quote:

Et j'avoue que je sèche un peu. Les seules solutions que j'entrevois
seraient nettement plus compliquées à utiliser que de tout réécrire à
chaque fois.

Donc, si quelqu'un a une solution simple et élégante...
Merci d'avance !


As -tu jeté un coup d'oeil dans la bibliothèque Loki,
du côté des Typelists ?

Je pense que c'est juste ce qu'il te faut...

--
-Stan



Back to top
Loïc Joly
Guest





PostPosted: Thu Sep 08, 2005 6:23 pm    Post subject: Re: Des char* en pagaille Reply with quote



Fabien LE LEZ a écrit :
Quote:
Bonjour,

Une fonction de l'API Windows s'écrit à peu près ainsi :

size_t GetModuleFileName
(HMODULE hModule,
char* buffer_nom_fichier,
size_t taille_du_buffer);

[snip pour rendre la chose utilisable]


Quote:
Maintenant, j'aimerais savoir s'il est possible de rendre ce code plus
générique, afin de ne pas tout réécrire pour une fonction

size_t AutreFonction
(char* buffer_nom_fichier, size_t taille_du_buffer,
double machin, int truc);

J'envisage une possibilité à partir de boost::bind et boost::function
(tous deux en voie d'introduction dans le standard). Un truc du genre
(non testé) :

std::string callFctWithCheckedBuffer(
boost::function<size_t( char* buffer, size_t bufferSize)> fct)
{
size_t taille_buf= 256;
for(;Wink
{
std::vector<char> buf (taille_buf);
size_t resultat= fct(&buf[0], buf.size());
if (resultat < taille_buf)
{
return std::string (buf.begin(), buf.begin()+resultat);
}
taille_buf*=2;
}
}

Que l'on pourrait appeler ainsi :

string str = callFctWithCheckedBuffer(
boost::bind(GetModuleFileName, module, _1, _2));
string str2 = callFctWithCheckedBuffer(
boost::bind(AutreFonction, _1, _2, machin, truc));

--
Loïc

Back to top
Sylvain Togni
Guest





PostPosted: Thu Sep 08, 2005 10:49 pm    Post subject: Re: Des char* en pagaille Reply with quote

Fabien LE LEZ a écrit :

Quote:
std::string GetModuleFileName (HMODULE module)
{
size_t taille_buf= 256;
for(;Wink
{
std::vector<char> buf (taille_buf);
DWORD resultat= GetModuleFileName (module, &buf[0], buf.size());
if (resultat < taille_buf)
{
return std::string (buf.begin(), buf.begin()+resultat);
}
taille_buf*=2;
}
}

Normalement on a pas à faire ce genre de choses, une api C sérieuse
va forcément prévoire une stratégie d'allocation des buffers pas
trop compliquée pour l'utilisateur.

En l'occurrence, puisque c'est un chemin de fichier qui est retourné,
ceci suffit :

std::string GetModuleFileName(HMODULE module)
{
char buffer[MAX_PATH + 1];
GetModuleFileName(module, buffer, sizeof(buffer));
return buffer;
}

D'autres fois, il faut s'y prendre en deux temps :

std::string RegQueryValue(HKEY key, std::string subKey)
{
// premier appel pour obtenir la taille
LONG size;
RegQueryValue(key, subKey.c_str(), NULL, &size);
std::vector
// deuxième appel pour remplir le buffer
RegQueryValue(key, subKey.c_str(), &buffer[0], &size);
return std::string(&buffer[0], size);
}

--
Sylvain

Back to top
Fabien LE LEZ
Guest





PostPosted: Thu Sep 08, 2005 11:03 pm    Post subject: Re: Des char* en pagaille Reply with quote

On Fri, 09 Sep 2005 00:49:51 +0200, Sylvain Togni
<sylvain.togni (AT) NOSPAMwanadoo (DOT) fr>:

Quote:
En l'occurrence, puisque c'est un chemin de fichier qui est retourné,
ceci suffit :

std::string GetModuleFileName(HMODULE module)
{
char buffer[MAX_PATH + 1];
GetModuleFileName(module, buffer, sizeof(buffer));

Mon code me paraît nettement plus robuste.

<semi-HS>
Suivant le header, MAX_PATH vaut quelque chose comme 255 ou 260.
Or, avec la fonction CreateFile, il semble qu'on puisse créer des
fichiers au nom nettement plus long. Je préfère donc éviter de
présumer d'une taille maximale. Ou plutôt, je sais que le code que
j'ai proposé marche tout le temps, tandis qu'avec ta méthode, il faut
s'assurer que la limite qu'on met est bien valide.

<< CreateFile
[...]
Windows NT: You can use paths longer than MAX_PATH characters by
calling the wide (W) version of CreateFile and prepending "\?" to
the path. The "\?" tells the function to turn off path parsing. This
lets you use paths that are nearly 32,000 Unicode characters long. >>


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.