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 fonctionnant en mode _MBCS mais pas en mode _UNICODE


Sujet :

MFC

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2008
    Messages : 54
    Points : 20
    Points
    20
    Par défaut DLL fonctionnant en mode _MBCS mais pas en mode _UNICODE
    Bonjour tout le monde, mon appli fonctionne en _MBCS comme en _UNICODE.

    J'ai créé une DLL qui stocke dans une 'multimap' des objets contenant des variable et nottament les ressources de la DLL au format "GIF".

    J'accède à un objet de cette 'multimap' dans mon programme au moyen d'une fonction comprise dans la DLL.

    La fonction dans la DLL ressemble à ce bout de code résumé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DLLDEC CImageProduit* GetImgProd(_string DescriptorID,CImageProduit::eProdImgType eType)
    {
    	multimap <_string, CImageProduit>::iterator it;
     
    	it = m_mapImgList.find(DescriptorID);
     
    	int iType = (int)eType;
    	for(int i=0;i<iType;i++)
    		it++;
     
    	return &it->second;
    };
    Quand je l'utilise dans le programme au format _MBCS tout se passe merveilleusement bien. Lorsque j'utilise le programme en _UNICODE( je n'oublie pas de faire une recompilation de la dll en _UNICODE) J'ai un message d'erreur au moment du "return &it->second;" qui dit :

    "Windows has triggered a breakpoint in Program.exe.
    This may be due to a corruption of the heap, which indicates a bug in Program.exe or any of the DLLs it has loaded.".

    Je ne sais pas si ça peut aider, mais je vous montre l'exportation de la function de la DLL. Cela vient d'un tuto de Farscape

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // Functions that can be exported
    #ifdef _WINDLL
    #define DLLDEC __declspec(dllexport)
    #else
    #define DLLDEC __declspec(dllimport)
    #endif
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    //===================================================================================
    // Use that function to return a pointer to a ImageProduit object
    //===================================================================================
     
    // The first argument is a DescriptorID'string that is coming from the Product's 
    // Database. The second is the type of image. It can be an Image, a Symbol
    // Image or a Localized Symbol Image. The function returns a CImageProduit object pointer
    // given all parameters for the selected image.
    DLLDEC CImageProduit* GetImgProd(_string DescriptorID,CImgTAProd::eProdImgType eType);
     
     
    //===================================================================================
     
    #ifdef __cplusplus
    }
    #endif
    Info supplémentaire : la DLL n'est pas pas une extension des MFC. Elle est liée dynamiquement et le programme est une appli MFC.

    Je ne sais pas trop quoi faire... si quelqu'un aurait une idée, elle serait la bienvenue.

    Je vous remercie d'avance.

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    salut,
    vérifie que tu utilises le même mode d'utilisation de la CRT dans le programme et la dll.
    dans l'onglet C++/ code generation /runtime library : tu dois avoir /MD en mode dll , /MT en mode static.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2008
    Messages : 54
    Points : 20
    Points
    20
    Par défaut
    Merci Farscape de ta réponse,

    J'ai remarqué que je n'ai pas expliqué ce qu'était _string... alors pour info:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef UNICODE
    #define _string std::wstring 
    #else
    #define _string std::string 
    #endif
    mon application tourne sous visual studio 2008 --> utilisation des MFC 9.

    L'application lie de manière statique les DLL. Utilisation donc de Multi-threaded Debug (/MTd) pour le mode Debug/Debug_Unicode.

    La dll que j'ai créée est une dll WIN32 sans utilisation des MFC. Utilisation de Multi-threaded Debug DLL (/MDd) en mode Debug/Debug_Unicode.

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ton parcours de la map est un peu bizarre et tu ne teste pas que l'iterateur est en fin de parcours, plantage assuré si c'est le cas...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int iType = (int)eType;
        for(int i=0;it!=m_mapImgList.end() && i<iType;i++)
            it++;
    if(it!=m_mapImgList.end()) return &it->second;
    else return NULL;

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2008
    Messages : 54
    Points : 20
    Points
    20
    Par défaut
    Merci Farscape, tu as raison j'ai un peu trop simplifié le code ^^.

    J'ai fais quelques tests et je me suis rendu compte que le problème était le suivant :

    J'ai une classe qui est connue aussi bien par l'appli principale que par la DLL.
    Dans la Dll j'ai plusieurs objets de cette classe.
    J'ai une fonction GetImgProd qui me retourne un objet de ce type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class A
    {
       int X;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    DLLDEC A GetImgProd(_string DescriptorID);
     
    A m_A;
     
    A GetImgProd(_string DescriptorID)
    {
    return m_A;
    }
    Le plantage survient donc toujours en _UNICODE et pas en _MBCS au moment du return m_A qui dit: "Windows has triggered a breakpoint in Program.exe.
    This may be due to a corruption of the heap, which indicates a bug in Program.exe or any of the DLLs it has loaded.".

    Faudrait-il rendre la classe exportable? et si oui comment?

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    si tu partages une classe entre ta dll et ton programme ,il serait judicieux de mettre cette classe dans une bibliothèque statique, et de l'utiliser dans la dll et dans le programme.
    un dll d'extensions permet l'export d'une classe mais oblige d'utiliser les mfc
    voir faq.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2008
    Messages : 54
    Points : 20
    Points
    20
    Par défaut
    Le problème a été isolé.

    En fait dans la fonction GetImgProd(...) se trouvant dans la DLL, je fais appel à un paramètre "_string" qui peut être un std::wstring pour l'UNICODE ou un std::string pour le MBCS.

    Au moment de la destruction de la variable, cela plante avec le fameux message de corruption de la pile.

    J'ai remplacé cette variable par "LPCTSTR" et cela fonctionne sans problème.

    Quel pourrait être la raison de cette corruption?????

    Si quelqu'un a une idée cela pourrait être très intéressant.

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Points : 17 323
    Points
    17 323
    Par défaut
    ma foi,
    j'ai un peu le même problème en ce moment:
    j'ai un projet qui utilise un dll en unicode qui fait appel à un lib statique en unicode (ziparchive)
    en release pas de problème , en debug ça plante a la fermeture, en release ok
    le même projet sans faire appel a une dll en travaillant en directe ça fonctionne.
    le projet avec la dll configurée en multi-bytes fonctionne aussi..
    voila je ne sais que penser bug dans ziparchive ou problème de contexte lié a la dll ?
    Et vu le nombre de problèmes que je rencontre sous vista avec vc9.0 ,plantage du compilateur et du linker .
    je ne suis sûr de rien....

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    303
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 303
    Points : 155
    Points
    155
    Par défaut
    Citation Envoyé par farscape Voir le message
    ma foi,
    j'ai un peu le même problème en ce moment:
    j'ai un projet qui utilise un dll en unicode qui fait appel à un lib statique en unicode (ziparchive)
    Si cela peut t'aider dans mon projet actuel j'utilise également ZipArchive compilée en lib statique unicode, ma config est la même que toi Vista VS2008
    la seule différence peut-être est que je lie statiquement les MFCs.
    Et cela fonctionne.
    J'ai également dans les directives de compilation de l'appli principale la déclaration de

Discussions similaires

  1. Réponses: 0
    Dernier message: 23/05/2014, 14h24
  2. [Hudson] Scripts fonctionnant en mode console mais pas sous Jenkins
    Par gbdivers dans le forum Intégration Continue
    Réponses: 1
    Dernier message: 31/08/2011, 17h07
  3. Réponses: 9
    Dernier message: 08/03/2006, 12h27
  4. Réponses: 4
    Dernier message: 27/09/2005, 22h00

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