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 :

Callback et erreur mémoire


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 92
    Par défaut Callback et erreur mémoire
    Bonjour à tous,

    J'ai un petit problème lors de la réalisation d'un projet. Histoire d'expliquer un peu comment ça marche : j'ai un programme qui appelle un activeX. Jusque là tout va bien.
    Mais ça se complique. Une callback est implémentée dans le programme appelant. Elle est ensuite appelée à partir de l'activeX. Tout ça fonctionne mais j'ai un problème : ça plante (erreur mémoire) lorsque je sors de la callback.

    Voici un bout de code pour comprendre :

    Programme appelant :
    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
     
    void maclasse::fonction()
    {
    wrapperActiveX.RegisterEventCallback(hdl, EventCallback, this); 
    wrapperActiveX.openURL(hdl, url);
    }
     
    void maclasse::EventCallback(HANDLE hdl, EVENT_TYPE p_event, void* params, void* paramsD) //statique
    {
       maclasse* pThis = static_cast<maclasse*>(pvAppData);
       pThis->eventCallback(hdl, p_event, params);
    }
     
    void maclasse::eventCallback(HANDLE hdl, EVENT_TYPE p_event, void* params)
    {
    ...//code fonctionnel
    }
    Du côté du source de l'OCX, ça donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int OCX::openURL(HANDLE hdl, char* url)
    {	
        return DLLFunction_open( hdl, url);
    }
     
    bool DLLFunction_open(HANDLE hdl, char* url)
    {
       ...
       if (m_pEventCallback) //m_pEventCallback = EventCallback lors de l'appel à RegisterEventCallback  
    	m_pEventCallback(ToHandle(), event, params, paramsD); //event = OpeningURL
       ...
    }
    Donc pour résumer :

    - Je registre ma callback en appelant une fonction de l'OCX en lui passant notamment le pointeur de fonction correspondant à ma callback (EventCallback).
    - J'appelle ensuite une autre fonction de l'OCX (opeNURL) qui elle-même appelle la callback :
    m_pEventCallback(ToHandle(), event, params, paramsD);
    Je vois bien au débugger que l'on passe dans la callback.
    - Une fois le traitement terminé, ça plante à la sortie de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void maclasse::EventCallback(HANDLE hdl, EVENT_TYPE p_event, void* params, void* paramsD) //statique
    {
       maclasse* pThis = static_cast<maclasse*>(pvAppData);
       pThis->EventCallback(hdl, p_event, params);
    }
    Au débugguer c'est après l'acolade de sortie que ça plante. Du côté OCX, je vois que je passe l'appel à la callback mais lorsque ça plante, je ne suis là aussi pas sorti de la fonction (DLLFunction_open) appellant la callback. Par contre le code suivant l'appel est exécuté sans problème.

    Quelqu'un a t-il déjà rencontré un problème comme celui-là? J'ai l'impression que c'est un problème de pile mais je vois pas d'où il pourrait venir...

    Merci d'avance!

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Cela ressemble effectivement à un problème de pile.

    Pour tester, je changerai la méthode d'appel de la fonction statique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void maclasse::EventCallback(HANDLE hdl, EVENT_TYPE p_event, void* params, void* paramsD)
    en rajoutant un __stdcall devant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void __stdcall maclasse::EventCallback(HANDLE hdl, EVENT_TYPE p_event, void* params, void* paramsD)
    Et si cela ne marche pas essaye avec les autres méthodes d'appel (c'est un peu empirique et pas très déterministe comme méthode mais j'ai pas mieux)

    regarde ici pour plus d'info (en anglais)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 92
    Par défaut
    Wow ça semble marcher . Merci beaucoup

    J'ai lu le lien mais j'avoue ne pas y comprendre grand chose...quelle est la différence entre ma fonction et celle utilisant la méthode d'appel stdcall?

    Je comprends bien qu'il y a quelque chose avec la pile mais je ne vois pas pourquoi ça ne fonctionnait pas avant...Si j'ai bien compris, c'est maintenant la fonction appelée qui est responsable de dépiler les paramètres. Avant celà c'était la fonction appelante (désolé j'ai un peu de mal avec la pile)?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Bon, je suis bien content que ton problème soit résolu.

    Maintenant, les explications (en admettant que la méthode d'appel implicite par défaut de ton compilateur soit __cdecl)

    La grosse différence se situe au niveau de qui doit nettoyer la pile après un appel de fonction :
    • __cdecl : Calling function pops the arguments from the stack, c'est l'appelant qui nettoie
    • __stdcall : Called function pops its own arguments from the stack, c'est l'appelé qui nettoie


    Si l'appelant et l'appelé ne s'entendent pas sur qui a la responsabilité du nettoyage de la pile, tu obteins ce que tu as eu, une corruption de pile
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 92
    Par défaut
    Merci, maintenant j'ai bien compris
    Au niveau compilateur. Si j'ai deux projets, les deux sont compilés sous VS 2003 pour l'un et 2005 pour l'autre (avec compilo Intel en plus).
    Y'aurait-il une différence entre les deux? Le compilo Intel y serait-il alors pour quelque chose?
    Peut-on voir la méthode d'appel utilisée quelque part (dans les propriétés du projet...)?

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par CodeCRC Voir le message
    Peut-on voir la méthode d'appel utilisée quelque part (dans les propriétés du projet...)?
    Bonjour,
    Le comportement par défaut peut être positionné dans les options de compilations (calling conventions (/Gd, /Gr, et /Gz pour Visual). J'imagine que pour le compilo Intel ça doit être la même chose. En revanche, je n'en connait pas les valeurs par défaut pour Intel. Pour visual, c'est /Gd : __cdecl.

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

Discussions similaires

  1. Message d'erreur : "Mémoire insuffisante [..]"
    Par mcroz dans le forum Access
    Réponses: 8
    Dernier message: 01/03/2007, 17h14
  2. Erreur mémoire insuffisante
    Par jpp81 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 27/01/2007, 07h31
  3. [MFC] Erreur mémoire
    Par leMehdi dans le forum MFC
    Réponses: 8
    Dernier message: 26/01/2006, 16h09
  4. message d'erreur "Mémoire insuffisante"
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 25/10/2005, 14h41
  5. Réponses: 1
    Dernier message: 16/05/2004, 17h56

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