IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Dll compilée avec Code::Blocks: lancer exception et la récupérer dans l'application


Sujet :

C++

  1. #1
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut Dll compilée avec Code::Blocks: lancer exception et la récupérer dans l'application
    Salut,

    J'ai créé une bibliothèque de classes qui fonctionne bien... du moins tant qu'elle reste en statique.

    Maintenant, j'aimerais donner la possibilité de la compiler sous la forme d'une bibliothèque partagée.

    Les directives préprocesseurs semblent correctes et il m'est donc possible de créer une bibliothèque partagée ou une bibliothèque statique sur les différent OS testés (du moins, j'arrive à obtenir la dll, le so, et/ou le .a, selon le système).

    Là où cela coince, c'est que cette bibliothèque est sensée lancer des exceptions qui doivent être récupérées par l'application qui l'utilise...

    Tant que je travaille avec la bibliothèque statique, il n'y a aucun problème, mais dés que j'essaye de travailler avec la DLL, les exceptions restent bloquées au sein de celle-ci.

    En effet, quand je crée un nouveau projet destiné à utiliser la dll, avec les bonnes caractéristiques et que j'écris le code tout simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main()
    {
    try
    {
     AlgoTrace::exceptiontest();//fonction spécialement créée pour l'occasion
                                //destinée à tester les exceptions ;)
    }
    catch(std::exception &e)
    {
        cout<<e.what();
    }
        return 0;
    }
    plutôt que de récupérer l'exception dans le catch, ainsi que je m'y serais attendu, j'obtiens le message de la mort:
    terminate called after throwing a instance of 'AlgoTrace::AlgoException'
    what(): une exception
    mais qui est exactement le même message que si j'avais appelé la fonction en dehors de tout bloc try...catch.

    Ce qui me rassure déjà, c'est que l'exception est bien telle que je m'attendais à l'avoir... sauf que j'aurais cru la récupérer dans mon application

    Quelqu'un aurait il donc une idée sur les paramètres à passer à Gcc (sous code::blocks) pour indiquer que les exceptions lancées par la DLL doivent en sortir

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    A mon avis il faut surtout ne pas laisser sortir d'exception d'une DLL, cf. C++, the real world, and link and binary compatibility.
    Donc oui c'est pénible, mais c'est après tout logique si on veut vraiment garantir qu'une bibliothèque partagée est vraiment utilisable en tant que telle.

    En pratique tu devrais faire quelque chose comme try dès l'entrée dans la DLL puis positionnement d'un bon vieux last error dans le catch, puis un get last error + throw dans l'application juste après chaque appel à la DLL...

    MAT.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Plutôt que de modifier ainsi une variable non-réentrante, il serait peut-être plus pratique de retourner un HRESULT à la place (on peut y mettre toutes les erreurs Win32).
    Ainsi, ça correspondrait au schéma HRESULT = Exception cher à COM et .Net...

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    En fait, et de manière à permettre de comprendre mon objectif:

    L'idée de cette bibliothèque est de fournir une "façade" pour tout le code métier d'une application graphique.

    L'application graphique permet à l'utilisateur d'ajouter, de modifier (supprimer) une série d'éléments de différentes sortes, mais les ajouts/modifications/suppressions doivent être "validés" par le code métier (la bibliothèque).

    Au cas où la validation d'une des modification échoue, c'est le code métier qui se charge de "faire le ménage", et qui devrait idéalement permettre à l'application graphique de disposer des informations sur "ce qui n'a pas été".

    Les échecs de validations sont gérés sur base de classes dérivant de std::exception (et meme plus précisément de std::runtime_error )

    La difficulté supplémentaire vient du fait que, c'est mis dans le cahier des charges, la bibliothèque doit être indépendante et portable (sous réserve éventuelle de compilation, nous nous comprenons bien sur ce fait ).

    L'idée étant de permettre d'utiliser cette bibliothèque avec différentes interfaces graphiques et/ou sous différents OS.

    La "cerise sur le gâteau" aurait consisté à permettre la création d'une bibliothèque partagée, mais il ne s'agit là que d'un plus facultatif.

    Cependant, je crains que les obligations de portabilité ne m'autorisent pas à prévoir un mappage sur HResult.

    D'un autre côté, en y réfléchissant, j'adhère tout à fait au problème soulevé sous la forme de
    une exception survenue dans une dll ne devrait pas en sortir
    Dés lors, peut être devrais-je envisager une solution alternative qui consisterait, pour les fonctions de façade à considérer les exceptions lancées comme valeur de retour une fois qu'elles ont été gérées

    Ainsi, mes fonctions de façade pourraient prendre une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    const AlgoException fonction(/*...*/)
    {
        try
        {
           /* tout ce qu'il faut, et qui est susceptible de faire foirer la validation*/
        }
        catch(const AlgoException& e)
        {
            /* gestion finale du ménage */
            return e;
        }
        return NoError();/* une variante de AlgoException qui représenterait...
                          * le fait que ca s'est bien passé
                          */
    }
    Est-ce que ce "détournement" de l'idée des exceptions vous parait cohérent

  5. #5
    Membre expérimenté

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Points : 1 543
    Points
    1 543
    Par défaut
    Ca me parait toujours dangereux, par exemple si la déclaration et/ou la définition de std::runtime_error (et std::exception) diffèrent entre la compilation de la DLL et la compilation de l'application, ça va poser problème.
    Même s'ils ne différent pas et qu'un même compilateur est utilisé de part et d'autre, pour peu qu'il y ait une certaine option de différente, ça peut suffire pour avoir une représentation en mémoire différente...

    En fait pour bien faire il faut même n'utiliser dans l'interface d'une DLL que des types de base dont on est sûrs qu'ils seront représentés de la même manière (comme int ou float).

    Tu ne peux pas vraiment couper aux codes d'erreurs (12 et 42 sont mes préférés ).

    Enfin après si ta bibliothèque n'est utilisée que dans un cadre très précis que tu peux contrôler, tu peux toujours imposer une certaine version d'un certain compilateur avec certaines options de compilation, ou demander à ce que l'ensemble soit toujours (re-)compilé comme un tout.
    Mais du coup autant faire une bibliothèque statique...

    MAT.

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Enfin après si ta bibliothèque n'est utilisée que dans un cadre très précis que tu peux contrôler, tu peux toujours imposer une certaine version d'un certain compilateur avec certaines options de compilation, ou demander à ce que l'ensemble soit toujours (re-)compilé comme un tout.
    Mais du coup autant faire une bibliothèque statique...

    MAT.
    Ben, cette bibliothèque, même si elle a des chances, à terme, de se retrouver sous license GNU/GPL, n'a que peu de chances de servir pour autre chose que pour le projet pour lequel elle est développée (à quelques variantes de compilateur, de bibliothèque graphique ou d'OS près)...

    De là à demander à ce que la bibliothèque et l'application soient compilées comme un tout, il n'y a en effet qu'un pas, et n'eut été le plaisir de fournir une dll, comme je l'ai dit, cela n'aurait été que la cerise sur le gâteau

    J'en déduis donc qu'il semble - a priori - impossible, et en tout cas déconseillé, de faire remonter une exception d'une dll vers l'application qui l'utilise, et j'abandonne "tout simplement" l'idée de fournir cette bibliothèque sous une autre forme que statique

    Je remercie tout le monde pour le temps passé à l'apport d'éléments de réponses, et considère le sujet comme clôt

    Maintenant, si certains avis veulent encore se faire connaitre, je reste preneur

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Compiler avec Code::blocks
    Par PP(Team) dans le forum C++
    Réponses: 4
    Dernier message: 06/06/2010, 15h07
  2. Hydrax 5.1 : compiler avec code::blocks
    Par Froyok dans le forum Ogre
    Réponses: 0
    Dernier message: 31/10/2009, 00h07
  3. [Installation DirectX]Compiler avec Code::Blocks
    Par elmodeno dans le forum Développement 2D, 3D et Jeux
    Réponses: 4
    Dernier message: 03/11/2007, 18h01
  4. Erreur compilation avec Code Blocks
    Par Ulver dans le forum wxWidgets
    Réponses: 3
    Dernier message: 10/04/2007, 22h26
  5. [kjAPI] Compilation avec Code::Blocks
    Par ThomasCh dans le forum Moteurs 3D
    Réponses: 5
    Dernier message: 17/10/2006, 09h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo