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 :

Pointeur échangé avec une api C


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut Pointeur échangé avec une api C
    Bonjour à tous,

    J'écris un programme C++ qui accède à des données d'un logiciel propriétaire via une api C.
    J'utilise des fonctions de l'api de la forme suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int GetData(blabla, int type_data, api_struct *return_data);
    Je choisi la donnée que je souhaite récupérer avec la variable type_data.
    Je fourni un pointeur de type api_struct qui recevra dans l'union data la donnée souhaitée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    typedef struct _api_struct
    {
        int type_data; /* Key indicating type of information */
        union
        {
    	int data1;
    	char *data2;
    	time_t data3;
    	int data4;
    	char *data5;
        } data;
    } api_struct;
    La fonction de l'api renseigne le pointeur fourni.

    L'accès se fait donc de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        api_struct *list_data;
        GetData(blabla, type_data2, list_data);
        ma_fonction_locale(list_data->data.data2);
    A la compilation j'ai le warning suivant :

    133: warning: 'list_data' is used uninitialized in this function

    Pourtant la documentation de l'api dit que la mémoire pointée par le pointeur retourné par la fonction est gérée par l'api.

    A l'exécution j'ai l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Process returned -1073741819 (0xC0000005)   execution time : 6.750 s
    Alors j'ai effectué la modification suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    api_struct list_data[1000];
    GetData(blabla, type_data2, list_data);
    ma_fonction_locale(list_data->data.data2);
    et même

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    api_struct list_data[0];
    GetData(blabla, type_data2, list_data);
    ma_fonction_locale(list_data->data.data2);
    Et ça marche. Mais si j'appelle la fonction plus d'une demi-douzaine de fois j'ai l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "La mémoire ne peut être read".
    Qu'est-ce que j'ai loupé ?

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Points : 725
    Points
    725
    Par défaut
    Bonjour,

    C'est facile, tu déclares un pointeur vers une structure, mais pas la structure elle-même. GetData reçoit donc un pointeur, qui pointe vers un endroit aléatoire de ta mémoire, mais certainement pas une structure de type api_struct.

    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        api_struct list_data;
        GetData(blabla, type_data2, &list_data);
        ma_fonction_locale(list_data.data.data2);
    "By and large I'm trying to minimize mentions of D in C++ contexts because it's as unfair as bringing a machine gun to a knife fight." - Andrei Alexandrescu

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Effectivement, ça compile sans warning et j'ai le même résultat.
    Mais j'ai toujours le plantage après 6 ou 7 appel de la méthode qui encapsule l'extrait de mon code.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Points : 725
    Points
    725
    Par défaut
    En même temps, comme tu n'as pas donné le reste du code de la méthode qui plante, je peux difficilement deviner d'où peut venir le problème...
    "By and large I'm trying to minimize mentions of D in C++ contexts because it's as unfair as bringing a machine gun to a knife fight." - Andrei Alexandrescu

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Toute mes méthodes encapsulant les fonctions de l'api sont comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    vector<string> ma_classe::get_truc() {
        vector<string> _liste;
        if (_opened) {
            cout << "Appel methode get_truc(truc)." << endl;
            api_struct list_data;
            GetData(_ptr_job, truc1, &list_data);
            _liste = (convertToVector(list_data.info.truc1));
            cout << "Code retour GetData(truc) : " << GetLastError() << endl;
        }
        return _liste;
    }
    L'espace mémoire est géré par l'api qui crée un thread pour chaque connexion (fait une fois au début : je n'ai rencontré aucun problème) aux données du produit. Chaque appel écrase les données de l'appel précédent. Il faut donc copier les données dans une autre structure (ici un vector de string) avant tout nouvel appel.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,

    Pourrais-tu nous fournir le code de convertToVector, ainsi que le code qui utilise le vecteur de chaines renvoyé

    A priori, cette fonction ne fait rien de mal ni de mauvais... Il faut donc aller "voir ailleurs" si les données manipulées le sont correctement
    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

Discussions similaires

  1. [nasm] problème avec une API window
    Par ctrlD dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 09/12/2011, 15h25
  2. [2.x] ->getToken()->getUser() avec une API
    Par johnbenz dans le forum Symfony
    Réponses: 1
    Dernier message: 06/12/2011, 13h23
  3. [Débutant] Communication avec une api
    Par james8484 dans le forum VB.NET
    Réponses: 7
    Dernier message: 13/07/2011, 11h30
  4. Utilisation EHcache avec une API propriétaire
    Par aroutha dans le forum Persistance des données
    Réponses: 0
    Dernier message: 05/08/2009, 12h23
  5. comparer deux fichiers avec une api windows
    Par sweetdreamer dans le forum Windows
    Réponses: 4
    Dernier message: 25/05/2006, 23h10

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