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 :

Probléme lors du passage d'un pointeur de vector<string> entre un dll et un exe


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut Probléme lors du passage d'un pointeur de vector<string> entre un dll et un exe
    Bonjour à tous,

    J'ai codé un DLL avec un fonction transformant un fichier en vector<string>, je ramène le pointeur du vecteur créé dans la partie DLL dans le main de mon exécutable windows et j'essaie d'en exploiter les données. J'obtiens des données cohérente (bon nombre de ligne) mais impossible à lire (donnée proche de l’orignal ou BUG pur et simple).

    Je pense que mon problème est lié à un soucis de l'intégrité de la mémoire (ça ou une mauvaise utilisation des pointeurs).
    Je vous explique (enfin je vais essayer surtout..) en détails.

    Coté DLL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    vector<string>* DllExport parse_file(string mon_fichier)                           //avec "#define DllExport   __declspec(dllexport)" en début de fichier source
    {
    	vector<string> mon_fichier_en_vector;
    	string ligne;
    		fstream fichier(mon_fichier.c_str());  // on ouvre en lecture
    		while(getline(fichier, ligne)) 		
    				{		mon_fichier_en_vector.push_back((ligne));		}
    		fichier.close();
    	return &mon_fichier_en_vector;
    }

    Coté main.exe :

    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
       HINSTANCE DLLHandle;
       DLLHandle = LoadLibrary("main.dll");
       typedef vector<string>*(*Type_parse_file)(string);    //Prototype de la fonction;
       Type_parse_file parse_file;                                     //Nom de la fonction dans mon main
       parse_file = (Type_parse_file)GetProcAddress(DLLHandle,"parse_file");    //on récupére l'addresse du dll chargé en mémoire
     
    //     ...etc....
     
      vector<string> *mymain=parse_file("mon_fichier_a_mettre_en_vector.txt");
    //jusque la c'est bon
      cout << (*mymain).size() << endl;
    //renvoi une taille conforme au nombre de ligne de mon fichier
    //par contre
    cout << (*mymain)[1] << endl;
    //va se mettre a marquer plus ou moins n'importe quoi
    En changeant la valeur de 1 (l'index de mon vecteur) j’obtiens soit un plantage, soit un affichage partielle du contenu de mon fichier mais ne correspondant pas forcément à la bonne ligne, voir plusieurs lignes d'un coup... Le plus curieux c'est qu'a force de tâtonner avec la commande (*mymain)[100].size() (au alentour de la centième ligne a peu prés je sais plus trop) j'obtiens un nombre de caractère sur la ligne correspondant bien a mon fichier de départ, j'ai même pu confirmer en modifiant le fichier et relançant le programme que la valeur changeait aussi. Par contre dés que j’essaie d'en lire le contenu avec cout << (*mymain)[100] << endl; tout plante.

    J'ai pu lire pas mal de truc à propos de fuite mémoire, de la commande malloc et autres problèmes/solution lié à la mémoire en général mais je dois bien avouer que là mes compétences sont bien trop limités et j'ai besoin d'un œil et d'une aide extérieur.

    Je chercherais bien du coté de la sécurisation de l'espace mémoire dans la partie code du DLL mais je ne sais même pas quel mot clé chercher sur le net. Je nage un peu.
    Ndlr : pour le moment j'utilise g++ sous windows.

    Merci

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je vais juste te poser deux questions pour essayer de te mettre sur la voie:
    1. Que renvoie ta fonction parse_file
    2. qu'advient-il de la variable locale mon_fichier_en_vector que cette fonction utilise



    Quand tu auras répondu à ces deux questions, tu sauras ce qui se passe, et tu pourras trouver une solution
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    1.elle renvoie un pointeur
    2.elle est 'détruite' une fois la fonction terminé

    Justement je me demande comment faire pour 'présérver' cette espace mémoire là.
    Je sais qu'il est super simple de renvoyé return vector<string> et de ne pas s'ennuyer avec les pointeurs, mais je risque d'aller vers la gestion de fichier de plus en plus gros et ca me semble dommage de 'copier' un vector<string> qui est déjà en mémoire non?

    Et alors la du coup je m'arrete net :
    1.Si je crée mon vector<string> dans le main
    2.Si j'envoi son pointeur à ma fonction dll pour exploitation et remplissage du vector<string>
    3.Je devrais pas avoir de probléme avec la variable vector<string>
    4.J'ai bon?

  4. #4
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    Un grand merci à toi koala,
    La méthode fonctionne, je prend le temps de venir poster une réponse propre mardi.
    Je pense que j'avais bien trop le nez dedans pour voir mon erreur qui était donc....
    ....Mauvaise utilisation du pointeur.
    Encore merci et bon weekend.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par neokal Voir le message
    1.elle renvoie un pointeur
    2.elle est 'détruite' une fois la fonction terminé
    Bien vu
    Justement je me demande comment faire pour 'présérver' cette espace mémoire là.
    Je sais qu'il est super simple de renvoyé return vector<string> et de ne pas s'ennuyer avec les pointeurs, mais je risque d'aller vers la gestion de fichier de plus en plus gros et ca me semble dommage de 'copier' un vector<string> qui est déjà en mémoire non?
    Je ne suis pas sur qu'il sera copié; il se peut -- à vérifier -- qu'il soit "simplement" déplacé
    Citation Envoyé par neokal Voir le message
    Et alors la du coup je m'arrete net :
    1.Si je crée mon vector<string> dans le main
    2.Si j'envoi son pointeur à ma fonction dll pour exploitation et remplissage du vector<string>
    3.Je devrais pas avoir de probléme avec la variable vector<string>
    4.J'ai bon?
    Ce serait un solution, mais elle poserait un autre problème: Tu dois essayer de faire en sorte d'avoir une barrière nette entre ton application et ta dll: l'application gère ses propres ressources, et la dll les siennes.

    Autrement dit :
    • Tout ce qui sort de la dll, l'application n'a pour seul droit de l'interroger, mais, toute modification ne peut être entreprise que par la dll.
    • De même, la dll n'a que pour seul droit que d'interroger ce que l'application lui transmet, mais ne peut en aucun cas le modifier.


    Si ton application transmet, sous une forme ou une autre, un tableau à ta dll pour qu'elle le modifie, tu brises ces deux règles, et cela ne pourra que poser problème par la suite
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre averti
    Homme Profil pro
    Responsable du parc et des réseaux de télécommunication
    Inscrit en
    Mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable du parc et des réseaux de télécommunication
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2017
    Messages : 20
    Par défaut
    Bonjour à tous,
    Voila pour continuer sur mon idée de la dérniére fois j'ai finalement bricoler ça :

    Coté DLL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void DllExport parse_file(string mon_fichier,vector<string> *mon_fichier_en_vector)			//avec #define DllExport   __declspec(dllexport)
    {
    	string ligne;
    		fstream fichier(mon_fichier.c_str());  // on ouvre en lecture
    			while(getline(fichier, ligne)) 		
    				{
    						(*mon_fichier_en_vector).push_back(ligne);
    					//	cout << ligne << endl;
    				}
    		fichier.close();
    }		//END parse_file

    et coté main.exe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       HINSTANCE DLLHandle;
       DLLHandle = LoadLibrary("main.dll");
          ... etc ...
      //Définition pour parse file,
       typedef void(*Type_parse_file)(string,vector<string>*);
       Type_parse_file parse_file;
       parse_file = (Type_parse_file)GetProcAddress(DLLHandle,"parse_file");
    Bien évidement coté dll j'ai bien la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #ifdef __cplusplus		
    extern "C" {
    #endif
    J'appel donc ma fonction via parse_file("mon_fichier_a_lire.txt",&mon_vector_string_toto);
    Et ça marche juste impeccablement bien, même si j’entends et je comprend tout à fait :
    Ce serait un solution, mais elle poserait un autre problème: Tu dois essayer de faire en sorte d'avoir une barrière nette entre ton application et ta dll: l'application gère ses propres ressources, et la dll les siennes.

    Autrement dit :

    Tout ce qui sort de la dll, l'application n'a pour seul droit de l'interroger, mais, toute modification ne peut être entreprise que par la dll.
    De même, la dll n'a que pour seul droit que d'interroger ce que l'application lui transmet, mais ne peut en aucun cas le modifier.
    Cependant un nouveau soucis semble se poser pour moi et pas forcément en lien avec ce que je viens de citer:
    L'utilisation du dll obtenu marche juste 'super bien' avec un main.exe compiler sous gcc mais j'ai quelques petits soucis que je ne comprend toujours pas (décidément!) lorsque je cherche à utiliser ce même dll dans un projet winform/c++ dans visual studio.
    Les appels à des fonctions simples ne gérant que des entiers, string (EDIT: ne marche pas pour les strings non plus ) et autre variables ne posent aucun problèmes.
    Par contre dés que je fait intervenir des vector<string> (je n'ai pas encore testé les vector<int>) la c'est plantage (ou non fonctionnement) général.
    J'avoue que je débute en winform et en visual studio plus généralement et je n'ai pas vraiment d'idée sur la "bonne" façon de faire correctement les déclarations.
    Par exemple :
    Coté DLL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    vector<string> DllExport test (void){                        //avec #define DllExport   __declspec(dllexport)
    vector <string> test;
    test.push_back("this_is_a_test");
    return test;
    }	//END
    Coté MyForm (dans la procédure d'un événement par exemple (pas propre je sais)) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    HINSTANCE DLLHandle;
    DLLHandle = LoadLibrary(L"main.dll");
    typedef vector<string>(*Type_test)(void);
    Type_test test;
    test = (Type_test)GetProcAddress(DLLHandle, "test");
    Que j'appelle donc via la fonction mon_vector_retour=test();
    Me renvoi toutes sorte d'erreur selon l'endroit ou je déclare tout ça et même selon l'endroit ou je déclare std::vector<std::string>mon_vector_retour;

    Voilà je pense que je fait clairement fausse route, mais j'avoue que ma volonté de faire se heurte à la réalité à cause de ma compréhension trop limité des méthode que j'essaie d'utiliser.

    J'hésite sur plusieurs pistes, visual studio n'aime pas les vector, j'ai mal compiler mon dll (j'utilise la commande 'g++ dll.cpp -shared -o main.dll -std=c++11 -static-libgcc -static-libstdc++') ou encor visual studio 'protége' les zones mémoires de ses programmes (ça n'explique pas pourquoi ma fonction test ne marche pas sauf vraiment si j'ai mal déclaré mes variables).

    Bref, merci par avance pour les lanternes..

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

Discussions similaires

  1. Problème lors du passage de l'API 8 à l'API 5
    Par Ryu2000 dans le forum Android
    Réponses: 0
    Dernier message: 17/05/2011, 10h04
  2. Problème lors du passage de mon site en local
    Par florianjoy54 dans le forum Langage
    Réponses: 2
    Dernier message: 14/03/2010, 13h14
  3. Problèmes lors du passage Oracle 10.2.0.1.0 en 10.2.0.3 ?
    Par MatthieuQ dans le forum Installation
    Réponses: 5
    Dernier message: 30/01/2009, 17h24
  4. Problème lors du passage du focus
    Par bruce207 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 20/05/2008, 18h19
  5. Problème lors du passage de variable
    Par popo dans le forum Flash
    Réponses: 1
    Dernier message: 14/01/2008, 11h46

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