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 

Création de macro
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Michaël Delva
Guest





PostPosted: Tue Sep 07, 2004 4:33 pm    Post subject: Création de macro Reply with quote



Bonjour à tous,

j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de
syntaxe pour vérifier le bon déroulement du code:

hr = this->ConnectFilters(pGraph,pInfTee,pMux);
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}

FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.

Je voudrais créer une macro me permettant de réduire le code, quelque chose
du style:

TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");

et qui ait le même comportement que le code ci-dessus...

Seulement je sais absolument pas utiliser les macros...

Une âme charitable pourrait-elle m'aider?

Merci d'avance!
Back to top
Richard Delorme
Guest





PostPosted: Tue Sep 07, 2004 5:16 pm    Post subject: Re: Création de macro Reply with quote



Michaël Delva a écrit :
Quote:
Bonjour à tous,

j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de
syntaxe pour vérifier le bon déroulement du code:

hr = this->ConnectFilters(pGraph,pInfTee,pMux);
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}

FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.

Je voudrais créer une macro me permettant de réduire le code, quelque chose
du style:

TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");

et qui ait le même comportement que le code ci-dessus...

Seulement je sais absolument pas utiliser les macros...

#define TEST_FAILED(hr, msg)
if (FAILED(hr)) {
ShowMessage(msg);
return false;
} else (void) 0

Je précise : les macros, c'est mal... surtout en C++. A mon avis, celle
ci est particulièrement retors car elle cache un return et donc le flow
réel du programme.

--
Richard

Back to top
Loïc Joly
Guest





PostPosted: Tue Sep 07, 2004 10:36 pm    Post subject: Re: Création de macro Reply with quote



Michaël Delva wrote:
Quote:
Bonjour à tous,

j'utilise DirectShow, et je me retrouve très souvent à employer ce genre de
syntaxe pour vérifier le bon déroulement du code:

hr = this->ConnectFilters(pGraph,pInfTee,pMux);
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}

FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien passé.

Je voudrais créer une macro me permettant de réduire le code, quelque chose
du style:

TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");

Pourquoi une macro ? Voici une fonction qui fait une chose assez semblable :

void testFailed(type_de_hr hr, std::string const &message)
{
if FAILED(hr)
throw (DirectShowException(message));
}

Avec type_de_hr et DirectShowException des types qui vont bien.

--
Loïc

Back to top
Michaël Delva
Guest





PostPosted: Tue Sep 07, 2004 11:24 pm    Post subject: Re: Création de macro Reply with quote


Quote:
Pourquoi une macro ? Voici une fonction qui fait une chose assez
semblable :

void testFailed(type_de_hr hr, std::string const &message)
{
if FAILED(hr)
throw (DirectShowException(message));
}

Avec type_de_hr et DirectShowException des types qui vont bien.


Les exceptions sont assez inconnues pour moi... En quoi throw
(DirectShowException(message)) peut retourner un false?

Et à quoi doit ressembler DirectShowException?

Merci d'avance!

Back to top
Fabien LE LEZ
Guest





PostPosted: Tue Sep 07, 2004 11:42 pm    Post subject: Re: Création de macro Reply with quote

On 07 Sep 2004 23:24:37 GMT, "Michaël Delva"
<michael_delva (AT) i_cant_remember (DOT) com>:

Quote:
Les exceptions sont assez inconnues pour moi...

Ben faut apprendre. Ou faire du C.

Quote:
En quoi throw
(DirectShowException(message)) peut retourner un false?

Il ne peut pas. Mais une exception est a priori plus adaptée qu'un
"return false".

Au pire, tu peux faire un :

void testFailed(type_de_hr hr, std::string const &message)
{
if FAILED(hr)
throw (DirectShowException(message));
}

void f_impl (...)
{
...
testFailed (...);
...
testFailed (...);
...
testFailed (...);
}

bool f (...)
{
try
{
f_impl (...);
return true;
}
catch (DirectShowException const& e)
{
cerr << e.what() << endl;
return false;
}
}

....mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter
de se coltiner des tests de valeurs de retour à tout bout de champ --
on teste l'erreur (i.e. try...catch...) au moment où on sait la
traiter.

Quote:
Et à quoi doit ressembler DirectShowException?

class DirectShowException: public std::exception
{
public:
DirectShowException (std::string const& msg) : message (msg) {}
char const* what() const { return message.c_str(); }
private:
std::string message;
};


--
;-)

Back to top
Michaël Delva
Guest





PostPosted: Wed Sep 08, 2004 12:03 am    Post subject: Re: Création de macro Reply with quote

Quote:
...mais j'ai bien dit "au pire". L'idée des exceptions, c'est d'éviter
de se coltiner des tests de valeurs de retour à tout bout de champ --
on teste l'erreur (i.e. try...catch...) au moment où on sait la
traiter.

Ok, parce que moi j'ai des fonctions qui ressemblent à ça:


bool __fastcall Create_Graph()
{
CComPtr<IBaseFilter> pInfTee;
hr = pInfTee.CoCreateInstance(CLSID_InfTee);
if (FAILED(hr))
{
ShowMessage("blabla");
return false;
}

hr = pGraph->AddFilter(pInfTee,L"Infinite Pin Tee Filter");
if (FAILED(hr))
{
ShowMessage("blabla");
return false;
}

// Add the File Source filter to the graph.
CComPtr<IBaseFilter> pFileSource;
hr = pGraph->AddSourceFilter(path_in, L"Source",&pFileSource);
if (FAILED(hr))
{
ShowMessage("blabla");
return false;
}

return true;
}

Comme ça dès qu'il y a une erreur je sors de la fonction...
Ce qui visiblement est un manière de faire à éviter...

Si je remplace par ce que vous venez de me dire:

class DirectShowException: public std::exception
{
public:
DirectShowException (const AnsiString & message) : message (msg)
{}
AnsiString what() const { return message; }
private:
AnsiString message;
};

void testFailed(HRESULT hr, const AnsiString & message)
{
if FAILED(hr)
throw (DirectShowException(message));
}

void __fastcall Create_Graph()
{
CComPtr<IBaseFilter> pInfTee;

testFailed(pInfTee.CoCreateInstance(CLSID_InfTee),"blabla pInfTee");
testFailed(pGraph->AddFilter(pInfTee,L"Infinite Pin Tee
Filter"),"blabla");

CComPtr<IBaseFilter> pFileSource;
testFailed(pGraph->AddSourceFilter(path_in,
L"Source",&pFileSource),"blabla"); }

Et c'est à l'endroit où je lance ma fonction Create_Graph que je fais
comme suit:

void toto()
{
try
{
Create_Graph();
}
catch (DirectShowException const& e)
{
ShowMessage(e.what());
}
}

C'est bien ça?

Back to top
Michaël Delva
Guest





PostPosted: Wed Sep 08, 2004 12:15 am    Post subject: Re: Création de macro Reply with quote

Et sachant que mon main() est enchassé dans un bloc comme celui-ci (par
défaut avec BCB6, mais je crois que c'est très recommandé de procéder de la
sorte):

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = "toto";
Application->CreateForm(__classid(TMainForm), &MainForm);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}

Ai-je besoin d'écrire toto comme ceci:

void toto()
{
try
{
Create_Graph();
}
catch (DirectShowException const& e)
{
ShowMessage(e.what());
}
}

Ou bien cela suffit-il??

void toto()
{
Create_Graph();
}

Et dernières questions:
* lancer une exception comme ce que vous me conseillez permet-il de sortir
de la fonction sans encombres? (tous mes pointeurs sont encapsulés par ATL,
donc je pense ne pas avoir de soucis avec ça)
* Dans le constructeur de certaines classes je pourrai donc être amené à
lancer une exception... Avant d'aller lire le chapitre qui y est consacré
dans le livre de Stroustrup demain, comment ça se passe dans ce cas?

Merci d'avance
Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Sep 08, 2004 12:46 am    Post subject: Re: Création de macro Reply with quote

On 08 Sep 2004 00:03:40 GMT, "Michaël Delva"
<michael_delva (AT) i_cant_remember (DOT) com>:

Quote:
Comme ça dès qu'il y a une erreur je sors de la fonction...
Ce qui visiblement est un manière de faire à éviter...

Avec les exceptions aussi, on sort de la fonction. Mais utiliser des
valeurs de retour à tire-l'arigot est sans conteste une manière très
lourde de s'en sortir.

Je te propose un exemple pour illustrer l'utilisation des exceptions
et des hiérarchies d'exceptions. Note que le style du reste du
programme (notamment la gestion de fichiers à la C) laisse à désirer,
mais c'est juste pour l'exemple.

Supposons que tu veuilles utiliser les fonctions de gestion de
fichiers de l'API Windows pour ouvrir un fichier, y lire deux nombres,
et y écrire la somme de ces deux nombres, quand l'utilisateur clique
sur un bouton.

class ExceptionGeneraleFichier: public std::exception
{
public:
ExceptionGeneraleFichier (std::string const& nom_fonction)
{
std::string message_erreur= FormatMessage (GetLastError()); /*
L'appel de ces deux fonctions de l'API Windows est plus compliqué,
mais tu vois le principe... */
message= "La fonction " + nom_fonction
+ " a renvoyé l'erreur " + message_erreur + ".";
}

char const* what() const { return message.c_str(); }

private:
std::string message;
};

class ExceptionManqueDePlace: public ExceptionGeneraleFichier
{
public: ExceptionManqueDePlace (std::string const& nom_fonction)
: ExceptionGeneraleFichier (nom_fonction) {}
};

void EnregistreChaine (...)
{
if (WriteFile (...) == ERROR)
{
if (GetLastError() == DISK_IS_FULL)
{
throw ExceptionManqueDePlace ("WriteFile");
}
else
{
throw ExceptionGeneraleFichier ("WriteFile");
}
}
}

void EnregistreNombre (..., int n)
{
EnregistreChaine (..., Formate (n));
}

std::string LireChaine (...)
{
if (ReadFile (...) == ERROR)
{
throw ExceptionGeneraleFichier ("WriteFile");
}
return resultat;
}

int LireNombre (...)
{
return Convertir (LireChaine (...));
}

Fichier OuvrirFichier (...)
{
if (CreateFile (...) == ERROR)
{
throw ExceptionGeneraleFichier ("CreateFile");
}

return ...;
}

void FermerFichier (...)
{
if (CloseHandle (...) == ERROR)
{
throw ExceptionGeneraleFichier ("CloseHandle");
}

return ...;
}

void g (...)
{
...= OuvrirFichier (...);
int n1= LireNombre (...);
int n2= LireNombre (...);
EnregistreNombre (..., n1 + n2);
FermerFichier (...);
}

void f (...)
{
try
{
g (...);
}
catch (ExceptionManqueDePlace const&)
{
SupprimerFichiersTemporaires(); /* Si on manque de place sur
disque dur, on supprime des fichiers inutiles... */
g(); /* ... puis on tente à nouveau */
}
}

void ClicBouton()
{
try
{
f();
}
catch (std::exception const& e)
{
AfficherMessage (e.what());
}
}




--
;-)

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Sep 08, 2004 12:52 am    Post subject: Re: Création de macro Reply with quote

On 08 Sep 2004 00:15:56 GMT, "Michaël Delva"
<michael_delva (AT) i_cant_remember (DOT) com>:

Quote:
* Dans le constructeur de certaines classes je pourrai donc être amené à
lancer une exception... Avant d'aller lire le chapitre qui y est consacré
dans le livre de Stroustrup demain, comment ça se passe dans ce cas?

L'objet n'est pas construit. Ce qui ne pose pas de problème, puisqu'en
sortant du bloc "try", l'objet aurait été détruit de toutes façons.

Exemple :

struct Machin
{
Machin() { if (quelque_chose) throw MonException(); }
};

void f()
{
try
{
Machin m;
m.f(); // [1]
}
catch (...)
{
cerr << "Une exception lancée !" << endl;
}

};

Dans la ligne [1], m est forcément construit, car si Machin::Machin()
a lancé une exception, on n'atteint jamais cette ligne.


--
;-)

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Sep 08, 2004 12:55 am    Post subject: Re: Création de macro Reply with quote

On 08 Sep 2004 00:15:56 GMT, "Michaël Delva"
<michael_delva (AT) i_cant_remember (DOT) com>:

Quote:
Ou bien cela suffit-il

??

Fais gaffe, ta touche "?" se coince.

Quote:
void toto()
{
Create_Graph();
}

Si les exceptions lancées sont des erreurs fatales, qui nécessitent
l'arrêt du programme, OK. Sinon, ça ne va pas.

Je me permets de modifier un peu mon programme précédent :

void ClicBouton()
{
try
{
f();
}
catch (ExceptionGeneraleFichier const& e)
{
AfficherMessage (e.what());
}
}

int main()
{
try
{
...
}
catch (std::exception const& e)
{
cerr << e.what() << endl;
}
}

Ainsi, si au cours de g() une exception non liée aux fichiers (du
style, manque de mémoire), on considère ça comme une erreur fatale et
le programme se quitte après avoir affiché le message sur cerr.


--
;-)

Back to top
Jonathan Mcdougall
Guest





PostPosted: Wed Sep 08, 2004 5:53 am    Post subject: Re: Création de macro Reply with quote

Quote:
Bonjour à tous,

j'utilise DirectShow, et je me retrouve très souvent à employer ce genre
de
syntaxe pour vérifier le bon déroulement du code:

hr = this->ConnectFilters(pGraph,pInfTee,pMux);

Tu es au courant que this-> est redondant dans la plupart des cas?

Quote:
if (FAILED(hr))
{
ShowMessage("Impossible de connecter pInfTee à pMux");
return false;
}

FAILED étant une macro de DIrectShow permettant de vérifier que hr est
différent de S_OK, la valeur de retour indiquant que tout s'est bien
passé.

Je voudrais créer une macro me permettant de réduire le code, quelque
chose
du style:

Mauvaise idée, les macros sont à éviter en C++.

Quote:
TEST_FAILED(this->ConnectFilters(pGraph,pInfTee,pMux),"Impossible de
connecter pInfTee à pMux");

et qui ait le même comportement que le code ci-dessus...

Seulement je sais absolument pas utiliser les macros...

Concernant la macro, tu as déjà eu des réponses.

Quote:
Une âme charitable pourrait-elle m'aider?

Une simple fonction serait plus adaptée à ton problème :

bool test_failed(HRESULT hr, std::string message)
{
if (FAILED(hr))
{
ShowMessage(message); // possiblement .c_str()
return false;
}

return true;
}


void f()
{
if ( test_failed( mafonction(), "probleme avec mafonction()") )
return;
}

ou encore

class MonException {};

void check(HRESULT hr, std::string message) throw (MonException)
{
if (FAILED(hr))
{
ShowMessage(message); // possiblement .c_str()
throw MonException;
}
}

void f()
{
try
{
check(mafonction(), "probleme avec mafonction()");
check(mafonction2(), "probleme avec mafonction2()");
check(mafonction3(), "probleme avec mafonction3()");
}
catch(MonException &)
{
// oups, clean up et sortie
}
}

Plusieurs designs sont possible, entre autre que check() mette le message
dans l'exception et le catch() pourrait être chargé de l'afficher. Tout
ceci dépend de ta situation et de tes connaissances.


Jonathan Mcdougall
Montréal, Québec



Back to top
Pierre Maurette
Guest





PostPosted: Wed Sep 08, 2004 6:57 am    Post subject: Re: Création de macro Reply with quote

"Michaël Delva" <michael_delva (AT) i_cant_remember (DOT) com> a écrit:

Quote:
Et sachant que mon main() est enchassé dans un bloc comme celui-ci (par
défaut avec BCB6, mais je crois que c'est très recommandé de procéder de la
sorte):
Bonjour Michaël,

Je me permets de vous signaler que l'aide en ligne de BCB6 (du moins
sur ma version) est bien faite sur le sujet des exceptions, et en
français.
Rentrer par l'index, taper "exception..", et voir "Exceptions",
"Exceptions C++", etc.
Penser dans chaque entrée à cliquer sur "Voir aussi".
Vous aurez ainsi une explication claire des exceptions Win32 (là, il
faudrait aller dans l'aide "SDK Windows" toujours dans l'EDI BCB6,
mais je ne pense pas que ce soit indispensable) et surtout leurs
encapsulation "Exceptions C++" et "Exceptions VCL/CLX".
--
Pierre

Back to top
Michaël Delva
Guest





PostPosted: Wed Sep 08, 2004 9:50 am    Post subject: Re: Création de macro Reply with quote

Tes explications, et une lecture attentive du chapitre concerné dans le
Stroustrup m'ont permis de comprendre les exceptions et par là même de
corriger mon code...

Merci!
Back to top
Michaël Delva
Guest





PostPosted: Wed Sep 08, 2004 9:54 am    Post subject: Re: Création de macro Reply with quote

Pierre Maurette <maurettepierre (AT) wanadoo (DOT) fr> wrote in
news:jnatj0pdkp8oit10kaot2us3bkhvjnsqlu (AT) 4ax (DOT) com:

Quote:
"Michaël Delva" <michael_delva (AT) i_cant_remember (DOT) com> a écrit:

Et sachant que mon main() est enchassé dans un bloc comme celui-ci
(par défaut avec BCB6, mais je crois que c'est très recommandé de
procéder de la sorte):
Bonjour Michaël,
Je me permets de vous signaler que l'aide en ligne de BCB6 (du moins
sur ma version) est bien faite sur le sujet des exceptions, et en
français.
Rentrer par l'index, taper "exception..", et voir "Exceptions",
"Exceptions C++", etc.
Penser dans chaque entrée à cliquer sur "Voir aussi".
Vous aurez ainsi une explication claire des exceptions Win32 (là, il
faudrait aller dans l'aide "SDK Windows" toujours dans l'EDI BCB6,
mais je ne pense pas que ce soit indispensable) et surtout leurs
encapsulation "Exceptions C++" et "Exceptions VCL/CLX".
--
Pierre

Merci, c'est une section que j'ai lu également...

Cependant, j'ai une question à ce sujet: pour mes exceptions personalisées,
vaut-il mieux les faire dériver de std::exception ou bien de
SysUtils::Exception de la VCL?

Je pencherai pour la deuxième solution, mais c'est pour confirmation...

Merci!

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Sep 08, 2004 11:48 am    Post subject: Re: Création de macro Reply with quote

On 08 Sep 2004 09:54:05 GMT, "Michaël Delva"
<michael_delva (AT) i_cant_remember (DOT) com>:

Quote:
pour mes exceptions personalisées,
vaut-il mieux les faire dériver de std::exception ou bien de
SysUtils::Exception de la VCL?

Pour le coup, mieux vaut bien lire la doc de ton compilo à ce sujet.
Mais si c'est possible, le plus simple est d'hériter des deux.


--
;-)

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

 
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.