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

MFC Discussion :

[dll] compatibilité


Sujet :

MFC

  1. #1
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut [dll] compatibilité
    Je reviens à la charge sur de l'inadmissible... Je programmais sur Code::Blocks, ce qui se passait super bien... jusqu'à ce qu'on me fournisse une bibliothèque C (.lib) compilé sous Visual 6.0. Et là c'est le drame.
    Même si l'édition de lien se fait correctement, le programme n'effectue point la tâche attendu...
    La lib alloue la mémoire pour les objets dans la DLL et la libére dans l'exe ce qui nécessite d'utiliser les bibliothèques multithread de VC++6.0.
    Du coup je suis en train de passer sur Visual C++.net 2003.

    Est-ce que la librairie devra être recompilé sous C++.net ??? Pourquoi tant d'incompatibilité dans un "même" language pour une DLL???

    Merci de votre soutien

  2. #2
    Membre émérite
    Homme Profil pro
    Consultant ERP
    Inscrit en
    Février 2004
    Messages
    644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Février 2004
    Messages : 644
    Par défaut
    Il ne s'agit pas d'une incompatibilité au niveau du langage, mais simplement du compilateur employé.

    Regarde les options de compilation de ta DLL.

  3. #3
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Les options de compilation sont pour la bibliothèque RunTime: DLL Multithreads...
    Je suppose que, donc, celà invalide tous les autres types de compilateurs pour le reste du développement?
    A moins que d'autres compilos utilise ce principe?

    J'ai posé la question au gars qui a développé la DLL, il utilise le principe des DLL MultiThreads car la réservation de mémoire est faite dans la DLL, doit être libérée dans l'éxécutable.
    Qu'en pensez-vous?
    Il n'y a pas d'autres méthodes?

    Merci!

  4. #4
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Non, pas de rapport mono/multithread. C'est lié à la crt, compilée en static ou en dll. La CRT = le code de la lib C/C++, = c'est là que se trouve malloc/free.
    Chaque VC++ a la sienne, et MingW a aussi la sienne. Ce qui fait que y'a plusieurs malloc dans ton même processus (celui de l'exe, celui de la dll). Et si tu compile la CRT en static, tu peux même avoir plusieurs fois le même malloc. Dans tous ces cas, ils sont incompatibles, c.a.d qu'il faut utiliser le même couple malloc/free.
    Une bonne règle de programmation c'est que celui qui alloue libère aussi. Tu viens de constater pourquoi c'est une règle généralement bonne à suivre.
    Une solution simple, c'est que ta dll exporte une fonction Free() que l'exe appelle pour libérer les objets. Le Free() de la dll utilisera en interne son free à elle, qui est associé à son malloc.
    Fait une recherche sur le forum VC++ aussi, mots clés CRT, dll, static...

  5. #5
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Merci beaucoup, je viens d'aller faire un tour dans le forum, et j'y ai trouvé une mine d'informations.
    Une solution simple, c'est que ta dll exporte une fonction Free() que l'exe appelle pour libérer les objets. Le Free() de la dll utilisera en interne son free à elle, qui est associé à son malloc.
    La lib étant écrite en C (malloc, free ...). Il faut effectivement libérer la mémoire à la main.
    Si elle était écrite en C++ (utilisation de conteneurs de la STL), alors que se passerait-il? (Je subodore qu'il n'y a pas de destructeur implicite...)

    Merci de ton aide précieuse, qui m'évitera des memory leaks !

  6. #6
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    La STL suit la même règle : elle va s'occuper de libérer ce qu'elle a alloué elle même, pour ses besoin internes. Si tu lui fait stocker des données que tu as alloué, elle ne les libérera pas pour toi.
    http://c.developpez.com/faq/cpp/?pag...elete_sequence
    En C++, y'a les pointeurs intelligents qui simplifient le vie:
    http://c.developpez.com/faq/cpp/?pag...S_intelligents
    mais dans le cas des dll, il faut se méfier... pareil pour la STL et plus généralement les templates qui se marient mal avec les dll.
    Par exemple le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // fonction de la dll
    std::string get_text();
     
    // utilisation depuis l'exe
    std::string s = get_text();
    va avoir des problèmes, pour la même raison d'une part, mais encore une autre en plus, qui est celle de l'instanciation des templates (il y a 2 std::string : celui de la dll et celui de l'exe). Là aussi on en a parlé, sur le forum C++ entre autre (warning C4251 de VC++...).

    Pour éviter les memory leaks, utilise les smart ptr, mais aussi de manière plus générale l'idiome RAII:
    http://c.developpez.com/faq/cpp/?pag...POINTEURS_raii
    qui va te faire aimer la programmation en C++

  7. #7
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    tu vas rire, c'est des tableaux que j'ai a gérer !!!
    Tu penses que l'utilisation de boost::shared_array va permettre à la DLL de gérer la mémoire toute seule?

  8. #8
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    C'est plus compliqué que ça. Il faut bien maitriser les concepts de CRT, dll et d'instanciation de template.
    Si ton exe et ta dll utilisent boost::shared_array, tous les deux vont compiler leur propre boost::shared_array, en double chacun. Chacun d'entre-eux utilisera le delete de la CRT configurée, qui peut être la même entre l'exe et la dll si la CRT est dll shared, ou différente si la CRT est static. Dans le dernier cas, ça fera boum. Dans l'autre cas, ça marchera, mais conceptuellement c'est pas terrible, car le boost::shared_array renvoyé par la dll ne sera pas le même boost::shared_array utilisé par l'exe, et inversement. Dans la réalité, ils seront identiques, c'est pour ça que ça marchera. Mais ça relève quand même pas mal du coup de bol. Il suffit que tu mettes à jour boost (avec modif de boost::shared_array) et recompile seulement la dll ou l'exe, et boum, crash incompréhensible. Ou simplement que tu compiles avec des options différentes. Bref, c'est très bancal.
    Une possibilité, pas toujours réalisable, c'est que la dll ou l'exe exporte son instanciation de boost::shared_array pour le type en question. Exporter une instanciation de template c'est pas toujours possible. Voir les discutions sur le warning C4251).
    En tous cas moi je te déconseille tout ceci. Utilise une interface "raw C", comme en Win32. Ta dll exporte 2 fonctions:
    - une qui renvoie la taille du tableau dont elle a besoin
    - l'autre qui reçoit le tableau alloué par l'exe (qui se chargera de le libérer) avec sa taille
    ou alors tu utilises des fonctions communes pour l'allocation, mais moi j'aime pas trop ce concept que la dll alloue et l'exe libère. Les fonctions communes, c'est la CRT shared (dll), ou les fonctions d'alloc Win32. Tu peux aussi carément t'orienter vers COM. C'est plus complexe, mais ça a été conçu pour pouvoir échanger des données/classes etc... entre plusieurs modules écrits dans des langages différents...
    Le mieux reste de te passer de dll.

  9. #9
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Merci pour ta réponse d'une grande précision. Je suis d'accord avec toi sur le principe : celui qui alloue, libère. Dans ce cas, c'est bien mieux d'allouer dans l'exécutable! D'ailleurs, toutes les librairies demandent au programmeur d'allouer eux-même la mémoire, ce qui est logique!
    J'ai discuté avec celui qui m'a passé la librairie avec ce concept hybride : j'alloue dans la DLL, tu libères dans l'exe.
    Il m'a soutenu que celà ne posait pas de problème puisque étant compilé en mode /MD, le malloc (par la DLL) et le free (par l'exe) se faisait sur la même pile...
    Est-ce exact? Ca me semble douteux...

    A la limite, il ferait mieux de fournir un .h avec les fonctions pour aller dans la base de données dedans non? Ca éviterait ces complications!

  10. #10
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Ce n'est pas la pile mais le tas (heap), au sens C/C++ (car il peut y en avoir plusieurs sous Windows). Si le tas C/C++ (celui de malloc/free) de la dll est de l'exe sont les mêmes, alors oui ça marchera, uniquement pour VC++. Et /MD effectivement a pour conséquence que les tas sont commun (CRT shared), mais en release. Il t'empêche ainsi de développer en debug . Ou alors il doit te filer une 2° dll compilée en /MDd.
    Ca soulève d'abord une remarque : on a donc ce "si" à gérer => risque supplémentaire de plantage (tu confirmes ? )
    Mais aussi une question : pourquoi faire une dll ? Normalement, c'est dans un but de réutilisabilité, et là tu restreins l'utilisation de ta dll au même compilateur (y compris la version), mêmes options de compilation. Il ne peut pas plutôt te filer ça sous forme de lib statique ?
    Si tu veux pouvoir utiliser un autre compilateur que le siens, /MD ne changera rien, vu que le compilateur utilisera sa propre CRT, et donc son propre tas.

  11. #11
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Tout celà confirme que le système choisi est un peu moyen .
    Il va falloir un effet changer de méthode. J'imagine la tête du type qui prendra la suite de mon programme quand il devra récupérer la lib pour la recompiler avec le compilateur qu'il utilise...
    En effet, je confirme, avec Code::Blocks, la librairie ne servait... à rien.

    Je crois que la DLL ne sert effectivement à rien, on va donc changer de méthode!

    Merci Aurélien pour ces réponses!
    J'en apprend tous les jours sur ce forum !

  12. #12
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    La dll peut être utile, mais soit elle fait le malloc et le free, soit elle ne fait aucun des deux.

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

Discussions similaires

  1. [DLL C++] Compatibilité de type avec Delphi
    Par almoude dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 28/10/2011, 14h49
  2. Réponses: 0
    Dernier message: 29/03/2010, 11h00
  3. Compatibilité libmysql323.dll avec MySQL 4.1
    Par Harry dans le forum Administration
    Réponses: 0
    Dernier message: 19/06/2008, 15h36
  4. Compatibilité avec d'autres machines - dll manquantes
    Par Ryuzaki dans le forum Windows
    Réponses: 2
    Dernier message: 13/03/2008, 19h08
  5. [VB6] DLL ActiveX : Probleme de Compatibilité de versions
    Par ironik dans le forum VB 6 et antérieur
    Réponses: 25
    Dernier message: 06/06/2006, 09h31

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