 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Fabien LE LEZ Guest
|
Posted: Thu Sep 08, 2005 4:50 pm Post subject: Des char* en pagaille |
|
|
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(;
{
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
|
Posted: Thu Sep 08, 2005 5:01 pm Post subject: Re: Des char* en pagaille |
|
|
"Fabien LE LEZ" <gramster (AT) gramster (DOT) com> a écrit dans le message de news:
[email]edq0i1lllqejh9vsjdu7ildq9crkn2aht6 (AT) 4ax (DOT) com[/email]...
| 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
|
Posted: Thu Sep 08, 2005 6:23 pm Post subject: Re: Des char* en pagaille |
|
|
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(;
{
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
|
Posted: Thu Sep 08, 2005 10:49 pm Post subject: Re: Des char* en pagaille |
|
|
Fabien LE LEZ a écrit :
| Quote: | std::string GetModuleFileName (HMODULE module)
{
size_t taille_buf= 256;
for(;
{
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
|
Posted: Thu Sep 08, 2005 11:03 pm Post subject: Re: Des char* en pagaille |
|
|
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 |
|
 |
|
|
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
|
|