|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Bonjour,
J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). La gestion d'erreurs dans cette bibliothèque fonctionne comme suit : on fournit une fonction "my_error_exit()", qui doit se démerder pour arrêter le code. (La fonction par défaut appelle exit().) Dans cette fonction, je vois deux choix possibles : 1- longjmp() (avec un setjmp() dans le code appelant) 2- throw une_exception; Au moins sur mon compilateur (VC++ 2008), la première solution est officiellement non gérée : "Do not use setjmp and longjmp in C++ programs; these functions do not support C++ object semantics." <http://msdn.microsoft.com/en-us/library/yz2ez4as(VS.80).aspx> Lancer une exception serait bien agréable, mais j'ai cru lire qu'il ne fallait pas laisser se propager une exception à travers du code C. Pour l'instant, j'ai pondu une interface en C qui contient un paquet de fonctions de ce style : boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) { if (setjmp (error_manager.setjmp_buffer)) { return 0; } jpeg_start_decompress (cinfo); return 1; } Si quelqu'un a une meilleure solution... Merci d'avance. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Fabien LE LEZ <gramster@gramster.com> writes:
> Bonjour, > > J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). > La gestion d'erreurs dans cette bibliothèque fonctionne comme suit : > on fournit une fonction "my_error_exit()", qui doit se démerder pour > arrêter le code. (La fonction par défaut appelle exit().) > > Dans cette fonction, je vois deux choix possibles : > 1- longjmp() (avec un setjmp() dans le code appelant) > 2- throw une_exception; > > Au moins sur mon compilateur (VC++ 2008), la première solution est > officiellement non gérée : > "Do not use setjmp and longjmp in C++ programs; these functions do not > support C++ object semantics." > <http://msdn.microsoft.com/en-us/library/yz2ez4as(VS.80).aspx> > > Lancer une exception serait bien agréable, mais j'ai cru lire qu'il ne > fallait pas laisser se propager une exception à travers du code C. > > > Pour l'instant, j'ai pondu une interface en C qui contient un paquet > de fonctions de ce style : > > boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) > { > if (setjmp (error_manager.setjmp_buffer)) > { > return 0; > } > > jpeg_start_decompress (cinfo); > return 1; > } > > > Si quelqu'un a une meilleure solution... Compiler la bibliothèque avec un compilateur C++ et utiliser les exceptions. -- __Pascal Bourguignon__ |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Mon, 07 Jul 2008 11:43:34 +0200, Pascal J. Bourguignon
<pjb@informatimago.com> wrote: > Fabien LE LEZ <gramster@gramster.com> writes: > >> Bonjour, >> >> J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). >> La gestion d'erreurs dans cette bibliothèque fonctionne comme suit : >> on fournit une fonction "my_error_exit()", qui doit se démerder pour >> arrêter le code. (La fonction par défaut appelle exit().) >> >> Dans cette fonction, je vois deux choix possibles : >> 1- longjmp() (avec un setjmp() dans le code appelant) >> 2- throw une_exception; >> >> Au moins sur mon compilateur (VC++ 2008), la première solution est >> officiellement non gérée : >> "Do not use setjmp and longjmp in C++ programs; these functions do not >> support C++ object semantics." >> <http://msdn.microsoft.com/en-us/library/yz2ez4as(VS.80).aspx> >> >> Lancer une exception serait bien agréable, mais j'ai cru lire qu'il ne >> fallait pas laisser se propager une exception à travers du code C. >> >> >> Pour l'instant, j'ai pondu une interface en C qui contient un paquet >> de fonctions de ce style : >> >> boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) >> { >> if (setjmp (error_manager.setjmp_buffer)) >> { >> return 0; >> } >> >> jpeg_start_decompress (cinfo); >> return 1; >> } >> >> >> Si quelqu'un a une meilleure solution... > > Compiler la bibliothèque avec un compilateur C++ et utiliser les > exceptions. > Très beau en théorie, mais en pratique, au moindre malloc sans cast, ca va casser. Et je passe sous silence les autres problèmes entre C et C++. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Tu peux utiliser les membres 'client_data' de la structure
'jpeg_decompress_struct' et 'error_exit' de la structure 'jpeg_error_mgr' pour personnaliser ta gestion des erreurs: METHODDEF(void) my_error_exit(j_common_ptr cinfo) { ggo_error * error; error = static_cast<ggo_error*>( cinfo->client_data ); *error = GGO_ERROR_IO; } ggo_error read_jpeg(const string & filename) { jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; ggo_error error = GGO_ERROR_NONE; cinfo.err = jpeg_std_error( &jerr ); cinfo.client_data = &error; jerr.error_exit = my_error_exit; jpeg_create_decompress( &cinfo ); if ( error != GGO_ERROR_NONE) { return ( error ); } // Etc. Rien ne t'empêche (j'imagine) d'avoir un traitement des erreurs plus fin à base d'exceptions. Je te conseille également de lire la doc qui est assez détaillée à ce niveau. Fabien LE LEZ wrote: > Bonjour, > > J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). > La gestion d'erreurs dans cette bibliothèque fonctionne comme suit : > on fournit une fonction "my_error_exit()", qui doit se démerder pour > arrêter le code. (La fonction par défaut appelle exit().) > > Dans cette fonction, je vois deux choix possibles : > 1- longjmp() (avec un setjmp() dans le code appelant) > 2- throw une_exception; > > Au moins sur mon compilateur (VC++ 2008), la première solution est > officiellement non gérée : > "Do not use setjmp and longjmp in C++ programs; these functions do not > support C++ object semantics." > <http://msdn.microsoft.com/en-us/library/yz2ez4as(VS.80).aspx> > > Lancer une exception serait bien agréable, mais j'ai cru lire qu'il ne > fallait pas laisser se propager une exception à travers du code C. > > > Pour l'instant, j'ai pondu une interface en C qui contient un paquet > de fonctions de ce style : > > boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) > { > if (setjmp (error_manager.setjmp_buffer)) > { > return 0; > } > > jpeg_start_decompress (cinfo); > return 1; > } > > > Si quelqu'un a une meilleure solution... > > Merci d'avance. > |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Jul 7, 10:04 am, Fabien LE LEZ <grams...@gramster.com> wrote:
> J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). > La gestion d'erreurs dans cette bibliothèque fonctionne comme > suit : on fournit une fonction "my_error_exit()", qui doit se > démerder pour arrêter le code. (La fonction par défaut appelle > exit().) > Dans cette fonction, je vois deux choix possibles : > 1- longjmp() (avec un setjmp() dans le code appelant) > 2- throw une_exception; > Au moins sur mon compilateur (VC++ 2008), la première solution est > officiellement non gérée : > "Do not use setjmp and longjmp in C++ programs; these functions do not > support C++ object semantics." > <http://msdn.microsoft.com/en-us/library/yz2ez4as(VS.80).aspx> En somme, elles n'appellent pas les destructeurs. Ça, on le savait déjà. > Lancer une exception serait bien agréable, mais j'ai cru lire > qu'il ne fallait pas laisser se propager une exception à > travers du code C. Ça dépend de l'implémentation. Sur la plupart des implémentations, ça ne pose pas de problèmes, sauf... il n'y a pas d'exceptions en C, et donc, le code s'attend probablement à ce que quand il appelle une fonction, cette fonction retourne d'où elle a été appelée (de façon à ce qu'il fait le ménage). > Pour l'instant, j'ai pondu une interface en C qui contient un > paquet de fonctions de ce style : > boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) > { > if (setjmp (error_manager.setjmp_buffer)) > { > return 0; > } > > jpeg_start_decompress (cinfo); > return 1; > } > Si quelqu'un a une meilleure solution... Tu n'as pas cité la documentation réele. Qu'est-ce qu'elle dit réelement à la place de « se démerder pour arrêter le code ». J'ai comme une forte doute que ce que ça veut dire, c'est qu'il faut arrêter le code, dans le sens de terminer le processus (pour que les ressources soient libérées, etc.). C-à-d que tu as, en gros, le choix entre exit(), abort() ou ExitProcess() (sous Windows), avec éventuellement l'édition d'un message de log, etc., avant. OK, j'ai régardé dans la doc, et elle dit que longjmp est OK. Dans ce cas-là, il est probable aussi qu'une exception marcherait, mais pourquoi prendre la risque. D'après ce que j'ai lu, ils ont prévu la possiblité des données client dans la structure de contrôle ; sers-t-en pour passer les informations qui t'intéressent, puis lever l'exception dans le cas d'erreur de setjmp. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Fabien LE LEZ wrote on 07/07/2008 10:04:
> > J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). ce n'est pas un nom univoque, plusieurs distribs portent ce nom (ou ils existent plusieurs branches) de laquelle parle-t-on ? > La gestion d'erreurs dans cette bibliothèque fonctionne comme suit : > on fournit une fonction "my_error_exit()", qui doit se démerder pour > arrêter le code. (La fonction par défaut appelle exit().) j'ai transcris en C++ une partie de la lib IJG Jpeg-6a il y a qlq années (partie compression uniquement), mis à part les appels invalides (que je traite en amont) seules les allocations nécessitaient un gestionnaire d'erreurs, je les ai regroupé et isolé par try catch. il n'est pas toujours indispensable de "mélanger c et c++", et si l'on peux s'en passer (parce que les srcs sont dispo) c'est sûrement mieux. Sylvain. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Mon, 7 Jul 2008 07:20:18 -0700 (PDT), James Kanze
<james.kanze@gmail.com>: >En somme, elles n'appellent pas les destructeurs. Ça, on le >savait déjà. En fait, ayant très peu d'expérience en C, c'est la première fois que je contemplais l'idée d'utiliser longjmp(). >> mais j'ai cru lire >> qu'il ne fallait pas laisser se propager une exception à >> travers du code C. > >Ça dépend de l'implémentation. Sur la plupart des >implémentations, ça ne pose pas de problèmes, sauf... il n'y a >pas d'exceptions en C, et donc, le code s'attend probablement à >ce que quand il appelle une fonction, cette fonction retourne >d'où elle a été appelée (de façon à ce qu'il fait le ménage). Ici, comme la doc préconise longjmp(), ça ne devrait pas poser de problème. Donc, en théorie, je devrais pouvoir lancer une exception, et lui faire traverser le code. >> Pour l'instant, j'ai pondu une interface en C qui contient un >> paquet de fonctions de ce style : > >> boolean JpegStartDecompress (struct jpeg_decompress_struct* cinfo) >D'après ce que j'ai >lu, ils ont prévu la possiblité des données client dans la >structure de contrôle ; sers-t-en pour passer les informations >qui t'intéressent, En fait, pour l'instant au moins, je n'ai pas besoin d'autre information que "la décompression a réussi" ou "elle a échoué". >puis lever l'exception dans le cas d'erreur de setjmp. Si j'ai bien compris, tu préconises de compiler la fonction JpegStartDecompress() en C++, et d'y lancer une exception ? J'avais mis ces fonctions dans un .c, histoire de les faire compiler par le compilateur C, et donc m'assurer que setjmp/longjmp ne pouvait en aucun cas interférer avec quelque objet C++ que ce soit. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Mon, 07 Jul 2008 23:02:03 +0200, Sylvain SF
<sylvain@boiteaspam.info>: >Fabien LE LEZ wrote on 07/07/2008 10:04: >> >> J'essaie d'utiliser une bibliothèque écrite en C (libjpeg). > >de laquelle parle-t-on ? La version présente sur le site de l'IJG. >j'ai transcris en C++ une partie de la lib IJG Jpeg-6a il y a qlq années >(partie compression uniquement), mis à part les appels invalides (que je >traite en amont) seules les allocations nécessitaient un gestionnaire >d'erreurs, Malheureusement la décompression est une autre paire de manches, puisqu'on peut avoir une erreur si le fichier n'est pas un fichier JPEG correct. |
|
![]() |
| Outils de la discussion | |
|
|