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++/CLI Discussion :

Echange d'objet entre classe managée et non managée


Sujet :

C++/CLI

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut Echange d'objet entre classe managée et non managée
    Bonjour,

    Voici mon soucis :
    J'ai une classe non managée qui fait appel à un objet d'une classe managée...

    ex
    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
    28
    29
    30
    31
     
    class A_unmanaged
    {
      ...
      int ma_fonctionA();
    }
    ...
     
    ref class B_managed
    {
     
         ...
      int ma_fonctionB(String ^ Var);
    }
    ...
     
    int  A_unmanaged::ma_fonctionA()
    {
     
        gcroot<B_managed ^> monB = gcnew B_managed(); //Ici tout va bien , mon objet est créée...
     
        gcroot<String ^> monParam = "YOUPIE";
     
       monB->ma_fonctionB(monParam);  //Ici ca va encore, c'est dans la fonction que va planter
    }
     
    ...
    int B_managed::ma_fonctionB(String ^ Var)
    {
       //Ici dès que j'essaie de faire qqchose avec Var (qui vient de monParam), ca plante !!
    }
    Donc, voilà, le paramètre créée dans ma fonction non-managée n'est pas exploitable dans ma fonction managée...

    Une idée ?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Essaie avec L"YOUPIE", puis avec gcnew String(L"YOUPIE") si ça ne marche toujours pas...
    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.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Et non, ca ne fonctionne pas...

    Une autre idée ?

    Je suppose que la variable instanciée dans la partie non managée n'est pas disponible dans la partie managée...mais il me semblait qu'un passage de paramètre créer une copie de l'objet...

    Maintenant, est-ce que la copie entre la pile standard et la pile managée est possible ?
    D'autant qu'il s'agit de "String ^" donc de "référence" (entre guillemets car je ne sais pas trop ce que signifie réellement le "^" )...
    J'ai essayé en passant des CString en paramètre, j'ai le même soucis...

    Une autre idée ?

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    J'ai essayé sur une autre fonction avec des int, ca marchait tres bien...

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Au fait : Même si ta classe elle-même n'est pas managée, si tu n'as pas mis de #pragma unmanaged, le code est toujours managé.

    Donc, tu devrais pouvoir y utiliser directement un B_managed^ et un String^, sans passer par gcroot<>.
    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.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Ma classe est #pragma managed ...mais ce n'est pas une "ref class" ...

    Et si je ne fais pas de gcroot<> ca ne marche pas...c'est le seul moyen d'utiliser des objets "ref class" dans une "class" normale (sachant que mon objet de type B_managed est en fait une donnée membre de A_unmanaged)

    Mais ce qui est super bizarre, c'est que j'ai exactement le meme fonctionnement entre ma classe A_unmanaged et une classe C_managed, qui marche nickel et avec B_managed, ca ne marche pas.... je ne comprends pas..

    Certainement une erreur stupide que je ne vois plus...

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Ce code compile parfaitement sans gcroot avec /clr...
    Code C++/CLI : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #include "stdafx.h"
    using namespace System;
     
    class A_unmanaged
    {
    public:
    	int ma_fonctionA();
    };
     
    ref class B_managed
    {
    public:
    	int ma_fonctionB(String ^ Var);
    };
     
    int A_unmanaged::ma_fonctionA()
    {
    	B_managed ^ monB = gcnew B_managed(); //Ici tout va bien , mon objet est créée...
    	String ^ monParam = "YOUPIE";
     
    	monB->ma_fonctionB(monParam);  //Ici ca va encore, c'est dans la fonction que va planter
    	return 0;
    }
     
    int B_managed::ma_fonctionB(String ^ Var)
    {
    	//Ici dès que j'essaie de faire qqchose avec Var (qui vient de monParam), ca plante !!
    	if(Var != nullptr)
    		Console::WriteLine(Var);
    	return 0;
    }
     
    void TestManaged(void)
    {
    	A_unmanaged a;
    	a.ma_fonctionA();
    }
    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.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Essaie la meme chose en mettant ton objet B_managed en données membres de ta classe A_unmanaged pour voir ...

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Bon effectivement, si mon objet B_managed n'est plus une donnée membre et que donc, je peux me passer du gcroot..et bien ca fonctionne...

    Là où je ne comprends pas c'est que dans mon appli je faisais la même chose avec une classe C_managed qui était donnée membre et déclarée avec gcroot et tout fonctionne....

    Enfin, bon, je peux me passer de B_managed comme donnée membre donc c'est bon... Merci beaucoup

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Pour les données membres en effet, il faut utiliser gcroot.
    Et ça marche...
    Code C++/CLI : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include "stdafx.h"
    #include <vcclr.h>
    #include "TestManaged.h"
    using namespace System;
     
    ref class B_managed
    {
    public:
    	int ma_fonctionB(System::String ^ Var);
    };
     
    class A_unmanaged
    {
    public:
    	A_unmanaged();
    	int ma_fonctionA();
    private:
    	gcroot<B_managed ^> monB;
    	gcroot<String^> maString;
    };
     
     
    A_unmanaged::A_unmanaged()
     : monB(gcnew B_managed), maString("COUCOU")
    {
    }
     
    int A_unmanaged::ma_fonctionA()
    {
    	String ^ monParam = "YOUPIE";
     
    	monB->ma_fonctionB(maString);
    	monB->ma_fonctionB(monParam);
     
    	int val = 0;
    	try{
    		val = Convert::ToInt32(maString);
    	} catch(FormatException^) {
    		val = 0;
    	}
    	val++;
    	maString = val.ToString();
    	return 0;
    }
     
    int B_managed::ma_fonctionB(String ^ Var)
    {
    	//Ici dès que j'essaie de faire qqchose avec Var (qui vient de monParam), ca plante !!
    	if(Var != nullptr)
    		Console::WriteLine(Var);
    	return 0;
    }
     
     
    void TestManaged(void)
    {
    	A_unmanaged a;
    	a.ma_fonctionA();
    	a.ma_fonctionA();
    	a.ma_fonctionA();
    }
    Produit en sortie:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COUCOU
    YOUPIE
    1
    YOUPIE
    2
    YOUPIE
    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.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Et si tu déclares et instancies MaString dans ta fonction , donc pas comme une donnée membre, ca fonctionne aussi ?

    (Meme si j'ai trouvé une solution, j'essaie de comprendre mon erreur)

    EDIT : ah oui, c'est ce que tu as fait avec "YOUPIE" ... bon...je ne comprends pas...


    RE-EDIT : Ca ne marche encore pas dès que j'essaie d'utiliser la variable...je vais m'aérer un peu et revenir sur mon code..

  12. #12
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    tu veux faire quoi au juste ?

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    JE veux faire exactement ce qui est dans l'exemple...

    Appeller une fonction d'un objet managé depuis une fonction d'un objet non managée...

    Mais ca parait super simple, en plus je l'ai déjà fait dans une autre partie de mon code avec un passage de "int". Mais dans mon deuxième cas, ca ne marche pas..

    Et à vrai dire, ca fait 10x que je vérifie mon code, et je ne vois pas où j'ai pu me tromper.. ca plante dès que j'essaie d'accéder au paramètre de ma fonction managée..
    ( si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int ma_fonctionB(String ^ Var)
    {
       return 1;
    }
    ca marche alors que si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int ma_fonctionB(String ^ Var)
    {
       if (Var != nullptr) //Ca ou meme < if(Var == "") > par exemple
        return 0;
      else
        return 1;
    }
    ca plante...

    J'ai alors penser que c'était le type String ^ qui avait du mal à être transmis en paramètre en non managé et managée, mais le test que l'on a fait hier semble me prouver le contraire.

    Ce qui veut dire que mon errreur est ailleurs, dans la conception de ma classe où quelquechose comme ca....
    J'ai la tête plus fraiche ce matin, je devrais pouvoir trouver....

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Attention : Var == nullptr n'est pas du tout la même chose que Var ==""
    N'oublie pas que l'opérateur == est surchargé pour les String^...

    Pourrais-tu poster un exemple compilable minimal qui montre le problème ?
    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.

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Citation Envoyé par Médinoc
    Attention : Var == nullptr n'est pas du tout la même chose que Var ==""
    Ca je sais, c'était juste pour montrer que dès que j'essaie de m'en servir, ca plante...
    Si je fais Var += " TEST" ca va planter aussi...

    Non, mais clairement, vu le nombre de test que j'ai fait, je pense que l'erreur est ailleurs et que je passe complètement à coté...

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    222
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 222
    Par défaut
    Bon, je savais bien que c'était une connerie...

    En fait, quand je créais mon exécutable je faisais "Générer > Générer MonTest" donc il ne récompiler que les fichiers modifiés...

    En fait, il faut qu'à chaque modification, je fasse bien "Générer > REgénérer MonTest" ... sans doute qu'à ce moment il crée les passerelles adéquates entre la pile managée et la zone mémoire non managée..

    Ca explique pourquoi je tournais en rond, un coup ca marchait, puis ca ne marchait plus...tout dépendait de ma méthode de compilation (complète ou incrémentielle...) ..

    Donc, un conseil, si faite du C++/CLI en mode mixte , évitez les compilations incrémentielles !!!

Discussions similaires

  1. [EJB] echange d'objet entre des javabeans
    Par archer dans le forum Java EE
    Réponses: 0
    Dernier message: 30/09/2010, 15h13
  2. Communication entre C# et C++ non managé
    Par MottetCCSF dans le forum C#
    Réponses: 0
    Dernier message: 13/07/2009, 17h27
  3. Echange d'objets entre web applications
    Par manube dans le forum Développement Web en Java
    Réponses: 2
    Dernier message: 13/11/2007, 11h01
  4. partager un objet entre classes
    Par kirua2150 dans le forum Access
    Réponses: 5
    Dernier message: 26/01/2007, 11h33
  5. Réponses: 7
    Dernier message: 07/01/2007, 13h50

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