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 :

instanciation problématique dans une méthode ActiveX


Sujet :

MFC

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut instanciation problématique dans une méthode ActiveX
    Bonjour,

    je suis en train de développer un activeX en C++ avec Visual Studio .NET, et j'ai un problème de bug (plantage de IE) quand je lance une méthode de mon activeX à partir du code JavaScript, et cette erreur vient apparemment d'une instanciation dans cette méthode.

    [EDIT]
    Pour rendre plus simple le problème que j'expose, est-ce que ce code peut poser des problèmes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          int Functions::Init(bool _a, bool _b) {
            this->myIPB = *(new IPB(_a, _b));
            return this->myIPB.Init();
          }
    [/EDIT]



    Explications plus longues...

    la méthode de l'activeX

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    BSTR CActiveXCtrl::Init(VARIANT_BOOL _a, VARIANT_BOOL _b)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
    	//L'instanciation qui pose problème
    	int res = funct->Init(true,true);
     
    	strcpy(resultat, funct->GetText(res));
    	CString strResult(resultat);
    	return strResult.AllocSysString();
    }
    la fonction init:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int Functions::Init(bool _a, bool _b) {
    	this->myIPB = *(new IPB(_a, _b));
    	return this->myIPB.Init();
    }
    le constructeur de la classe IPB:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    IPB::IPB(bool _a, bool _b) {
    	pObject = NULL;
    	this->res = _a;
    	this->comp = _b;
    }
    Quand je lance la méthode Init(true,true), internet explorer plante et mon debug me dit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int Functions::Init(bool _a, bool _b) {
    >>>erreur ici	this->myIPB = *(new IPB(_a, _b));
    	return this->myIPB.Init();
    }
    avec:
    this 0xcdcdcdcd
    |_>myIPB {pObject=??? res=??? comp=???}
    |_> pObject CXX0030 expression cannot be evaluated
    |_> res CXX0030 expression cannot be evaluated
    |_> comp CXX0030 expression cannot be evaluated

  2. #2
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    Autre chose avant de terminer:

    j'ai instancié cette méthode dans le constructeur de mon activeX, et à ce niveau là, ça passe , plus d'erreur!

    voyez-vous quel est le problème?

    merci d'avance

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    j'ai testé avec une autre méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    BSTR CActiveX2Ctrl::SXOpenPBX(BSTR IpAddress)
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
     
     
    	// TODO: Add your dispatch handler code here
     
    	int res = funct->OpenPB("test");
    	CString strResult(funct->GetText(res));
     
    	return strResult.AllocSysString();
    }
    et effectivement j'ai l'impression que je perds mon objet IPB, pourtant instancié dans le constructeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CActiveX2Ctrl::CActiveX2Ctrl()
    {
    	InitializeIIDs(&IID_DActiveX, &IID_DActiveXEvents);
     
    	Functions* funct = new Functions();
     
    	int res = funct->Init(true,true);
    	strcpy(resultat, funct->GetText(res));
    }
    avec la fonction init qui pour info est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int Functions::Init(bool _a, bool _b) {
       this->myIPB = *(new IPB(_a, _b));
       return this->myIPB.Init();
    }

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    Si cela peut aider, l'erreur retournée par Internet Explorer est

    Unhandled exception at 0x013d3841 (ActiveX.ocx) in IEXPLORE.EXE: 0xC0000005: Access violation writing location 0xcdcdcdd1.

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    j'ai entendu dire que cette erreur pouvait venir d'un problème de gestion de la mémoire par windows, qui supprimerait, sans sourciller, l'objet créé par ma méthode, est-ce que cela parle à quelqu'un ?

    et y'a t'il un moyen de dire, si le problème venait de là, à ce "garbage collector" que mon instance n'est pas une poubelle (ok elle est moche, mais elle m'est drôlement utile..)

  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
    Windows ne décide certainement pas tout seul comme ça de supprimer un objet. De plus c'est COM, et pas Windows. Les objets sont gérés via un compteur de référence.
    L'erreur que tu as c'est un bug quelque part, ça peut être du à tout et b'importe quoi. Vu qu'elle se produit dans ActiveX.ocx, pour moi c'est lui qui se vautre. Si c'est ton ActiveX, essaye de le déboguer.

  7. #7
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    ok, merci, donc pas de souci avec le garbage collector windows, je disais ça tout simplement parceque le projet est réalisé sous Visual .NET, et, parait-il, sous .NET le code C++ serait géré différemment (je n'en suis pas du tout sûr)


    mais le fait que mon objet ne disparaisse que dans les méthodes activeX externes me fait penser que celà ne vient pas de mon implémentation, encore une fois je ne suis sûr de rien.

    est-ce que le code que j'expose ci dessus parait être erroné ou ambigu sur certains points?

  8. #8
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    Pour rendre plus simple le problème que j'expose, est-ce que ce code peut poser des problèmes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          int Functions::Init(bool _a, bool _b) {
            this->myIPB = *(new IPB(_a, _b));
            return this->myIPB.Init();
          }
    (cf 1er post)

  9. #9
    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
    VC++.Net sait aussi compiler du pseudo C++ pour .Net, mais c'est autre chose. Dans ton cas, tu ne t'en sert pas, tu es en C++ natif, et il n'y a pas de garbage collector.
    Pour ton problème je peux pas trop m'y plonger, mais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int Functions::Init(bool _a, bool _b) { 
       this->myIPB = *(new IPB(_a, _b)); 
       return this->myIPB.Init(); 
    }
    ça me parrait super louche comme pratique. Est-ce que IPB a un constructeur de recopie ?

  10. #10
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    je dois t'avouer que je ne sais pas ce qu'est qu'un constructeur de recopie (je vais jeter un coup d'oeil de suite d'ailleurs), mais pour répondre à ta question, j'imagine que non il n'y en a pas

    ce pointeur sur objet est sensé être là pour stocker cet objet dans un membre de la classe Function, mais je suis d'accord que c'est assez tourmenté comme façon de faire

    penses-tu que je devrais faire ceci différemment ?

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    ben... ici, myIPB semble être tout sauf un pointeur...
    puisque tu lui affectes directement un objet...

    Pourquoi ne pas en faire tout simplement un pointeur, affecté avec un simple new ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  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
    http://c.developpez.com/faq/cpp/?pag...tructeur_copie

    Tu réinitialises ton objet (si j'ai bien compris) en effectuant une copie d'un nouveau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this->myIPB = *(new IPB(_a, _b));
    ça peut se décomposer ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IPB temp( _a, _b );
    this->myIPB = temp;
    // destruction de temp
    Note que je passe par un objet alloué sur la pile, et non par un new, car il faut un delete...

    si tu n'a pas de constructeur spécial pour la copie, this->myIPB devient une copie conforme de temp. Problème : si temp possède un pointeur pObject, tu obtiens 2 objets IPB (temp et myIPB) qui pointent vers le même pObject. Et lorsque temp est détruit, temp.pObject est (normalement) libéré, du coup le pointeur pObject de myIPB pointe vers n'importe quoi. Le plantage est assuré.
    Le constructeur par recopie va se charger de dupliquer pObject.
    Mais dans ton cas je ne suis pas sûr que ce soit la cause, vu que tu passes par une allocation dynamique, qui n'est pas libérée. Tu as donc une fuite de mémoire.
    Moi je te propose de revoir ton code et de créer une fonction Reste() par exemple, ou de modifier Init ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    IPB::IPB(bool _a, bool _b) { 
        this->Init( _a, _b );
    } 
     
    int Functions::Init(bool _a, bool _b) { 
       return this->myIPB.Init( _a, _b ); 
    }
    Je viens juste de voir ton commentaire ">>>erreur ici", ça me conforte dans l'idée du pblm de recopie.

  13. #13
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    je me suis penché sur ta solution Aurélien (d'ailleurs merci d'avoir étudié mon problème) mais il semble que rien y fait, ça plante toujours sous IE, pourtant il me semble que j'ai bien passé l'objet par copie.

    En effet, j'ai surchargé l'opérateur = qui passe alors l'objet par copie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    IPB& IPB::operator=(const IPB& ipb) {
    	if(this==&ipb)
    		return *this;
    	this->a = ipb.a;
    	this->alive = ipb.alive;
    	this->b = ipbx.b;
    	this->primaryPB = ipbx.primaryPB;
    	this->pObject = ipb.pObject;
    	if(strlen(ipb.IPaddress)!=0) {
    		this->IPaddress = new char(strlen(ipb.IPaddress));
    		strncpy(this->IPaddress, ipb.IPaddress, 10);
    	}
    	return *this;
    que j'utilise ainsi


    Le coté bizarre de la chose est que j'ai créé le même projet mais cette fois ci en Win32, et sous Win32, cela fonctionne, alors que dans mon activeX MFC non.

    J'aurais donc voulu savoir comment sont manipulés les objets dans une méthode activeX?

  14. #14
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    pour info je passe mon projet sous visual 6

    j'ai pas confiance avec visual .net, c'est le mal, il est marabouté, j'en suis sûr.

    je me demande toujours comment un projet peut fonctionner en mode win32 et pas en mode activeX.

  15. #15
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 152
    Par défaut
    finalement ca marche, sans que je ne sache vraiment pourquoi le programme se plantait...

Discussions similaires

  1. Réponses: 1
    Dernier message: 10/10/2006, 15h14
  2. "ajouter une méthode dans une méthode"
    Par Zorgloub dans le forum Langage
    Réponses: 1
    Dernier message: 09/04/2006, 12h53
  3. passer la valeur d'un return dans une méthode
    Par belukrin dans le forum Langage
    Réponses: 1
    Dernier message: 25/03/2006, 06h58
  4. [VB.NET] Declaration problématique dans une classe
    Par joefou dans le forum VB.NET
    Réponses: 8
    Dernier message: 01/03/2006, 11h38
  5. Réponses: 2
    Dernier message: 15/11/2004, 15h12

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