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 :

stockage d'une référence


Sujet :

C++/CLI

  1. #1
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut stockage d'une référence
    bonjour à tous ,
    je voudrais stocker une réference a un objet dans une ref classe
    et je ne trouve pas soit la méthode ou la syntaxe de déclaration appropriée.
    exemple:
    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
    using namespace System;
    //using namespace System::Collections;
     
    public ref class toto
    {
    public:    
        String ^varRef;
     
        void Set(String ^% v)
        {        
            v="affection par référence";
            varRef=v; // fait une copie ne permet pas de garder la reference.
            varRef="fonctionne ? (non  normal)"; // je veux stocker la référence
        }
    };
     
    int main(array<System::String ^> ^args)
    {
        Console::WriteLine(L"Hello World");
     
        String ^s="abc";
        toto ^c= gcnew toto;    
        c->Set(s);
       // s contient :"affection par référence" 
    }
    le passage par référence de la string "s" dans la méthode Set permet la modification de la source avec la variable "v" (pas de problème).
    mais comment garder la référence ou une adresse de la variable passée en référence dans ma classe ?
    si vous avez une idée de la manière de procéder je suis preneur...
    Merci d'avance.

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Première question : Est-ce qu'en C# l'équivalent de cette chose serait possible. Je ne crois pas. Il va donc falloir sortir de la partie pure CLI du langage, et aller vers la partie plus C++.

    On pourrait vouloir stocker un pointeur vers la chaîne, sauf que la CLR est en droit de bouger cette chaîne en mémoire à sa convenance. Il va donc falloir la pinner. Donc, je partirais vers l'utilisation d'un gcroot, ou directement de GCHANDLE. Mais je ne sais pas trop si ça pourrait marcher... Peut-être faudra-t-il modifier l'interface de set.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    merci pour la piste ,gchandle à l'air d'être la bonne voie , même si ça ne fonctionne pas encore !.
    pfff c'est si simple à faire en C++ et la je galère.

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    j'ai fais ceci que ne fonctionne pas comme je veux:
    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
    public ref class toto
    {
    public:		
    	IntPtr handle; 
    	void Attach(String ^% v)
    	{		
    		v="affection par référence"; // a ce moment s est egal à:affection par référence, normal !!!
    		GCHandle gcHandle = GCHandle::Alloc(v);
    		handle = static_cast<IntPtr>(GCHandle::ToIntPtr(gcHandle));
    	}
    	void affect(String ^str)
    	{
       	        String ^ targetStr = safe_cast< String ^ >(static_cast<GCHandle>(handle).Target);
    		// ici targetStr == "affection par référence"
    		targetStr=str; // a ce moment s est toujours egal à :affection par référence et pas à toto 
    	}
    };
     
     
    int main(array<System::String ^> ^args)
    {
        String ^s="abc";
        toto ^c = gcnew toto;
        c->Attach(s);
        c->affect("toto"); // n'affecte pas s 
        Console::WriteLine("s==toto {0}",s=="toto"); // affiche false
    }
    j'ai fais des essais avec gcroot non concluants ,meme problème.
    je veux vraiment stocker l'adresse de la référence et pas une copie du contenu ..
    si quelqu'un à une idée sur la chose j'en serais ravi.

  5. #5
    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
    Salut

    Oula, ca fait longtemps que j'ai pas fait de C++

    j'ai pas trop compris ce que tu voulais faire, en même temps, j'ai 39,5°C de fièvre

    t'as essayé avec le % ?
    http://dotnet.developpez.com/faq/cpp...ckingreference

    t'as le pointeur interne aussi : http://dotnet.developpez.com/faq/cpp...nteriorpointer
    voir le pointeur épingle : http://dotnet.developpez.com/faq/cpp...syntaxe#pinptr

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    merci pour ces pistes je vais regarder si ça peut me convenir ,
    Soigne toi bien

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    J'ai un peu réfléchi à ton problème, et je me dis que je n'ai pas assez d'informations sur ce que tu veux faire, et quelle latitude tu as pour y parvenir.

    Reprenons ton exemple, un peu modifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main(array<System::String ^> ^args)
    {
        String ^s="abc";
        String ^s2=s;
        toto ^c = gcnew toto;
        c->Attach(s);
        c->affect("toto"); // n'affecte pas s 
        // Veux-tu ici que s2 soit égal à "toto" ?
        Console::WriteLine("s==toto {0}",s=="toto"); // affiche false
    }
    Si la réponse à la question est oui, j'ai envie de dire qu'à part pinner la chaîne, puis hacker sa représentation interne en écrivant directement en mémoire, je ne vois pas trop comment ce genre de chose pourrait être écrit.

    Si la réponse est non, seul s est affecté, peux-tu changer le prototype de la fonction, pour passer une bonne vieille référence C++ ? C'est clairement le plus simple.

    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
    using namespace System;
     
    ref class StringModifier
    {
    public:
    	StringModifier(String ^&s) : myStringRef(s) {}
    	void Affect(String ^s) { myStringRef = s; }
     
    private:
    	String ^& myStringRef;
    };
     
    int main()
    {
    	String ^s = "toto";
    	String ^s2 = s;
    	StringModifier ^modif = gcnew StringModifier(s);
    	modif->Affect("tutu");
    	Console::WriteLine("s == {0}", s); // affiche false
    	Console::WriteLine("s2 == {0}", s2); // affiche false
    }
    Remarque : Si tu tiens à une fonction Attach plutôt qu'au constructeur, il te faudra passer par un String ^* plutôt qu'un String ^&, et l'écriture sera mins sympa.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    à la question la réponse est oui ^^,
    j'explique mon sujet :
    je développe une assembly en c++/cli pour pour permettre d'accéder à un séquentiel indexé disponible en C++ pour des applications c#
    voila pour le contexte général.
    l'utilisateur en C# pour déclarer une table procéderait comme suit:
    c'est un exemple simplifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
       DBInterface pFile = new DBInterface("famille",4 , 0);
       String     m_StrCle="";        // Code  famille                     
       String     m_StrNom=""; 
    // description du record de la table
       pFile.AddItem(ref m_StrCle,4); //clef sur 4
       pFile.AddItem(ref m_StrNom);
    // initialisation
       pFile.InitRecord();
       pFile.GetFirstRecod(); // cherche le premier record de la base
       // ici les variables strCle et strNom sont remplies ....
    Dans la pratique on déclarera une classe héritée et les variables du record seront des données membres.
    Donc dans ce contexte j'ai besoin de stocker les adresses des différents
    objet constituant un record pour leurs mises à jour indirectes par d'autres méthodes comme GetFirstRecord() de l'exemple.
    j'espère que c'est plus clair...

    je vais tester le String ^* pour voir.

    Merci pour la piste.

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Ma proposition demandait que l'appel de la fonction d'enregistrement soit fait en CLI, ce qui n'est pas le cas...

    Bien entendu, le plus simple serait que l'utilisateur enregistre une classe possédant les strings, au lieu d'enregistrer les strings elles mêmes... Mais je suppose que ce n'est pas l'interface pressentie...

    Est-ce que si l'utilisateur au lieu des strings standards utilise une classe à toi, mais qui a une interface d'utilisation très proche de celle de System::String, ça peut passer ? Ou encore des StringBuilders ?

    Finalement, ma proposition de hacker la représentation d'une string après l'avoir pinnée quelque-part en mémoire me semble peu envisageable. En effet, si le CLR lit le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       String     m_StrNom=""; 
       pFile.AddItem(ref m_StrNom);
    // initialisation
       m_StrNom = "Toto";
       pFile.GetFirstRecord(); // cherche le premier record de la base
       Console.WriteLine(m_strNom);
    Même si à force d'astuce on a réussi à changer le contenu de la chaîne m_StrNom, le compilateur peut lors de sa phase d'optimisation remplacer la dernière ligne par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       Console.WriteLine("Toto");
    Puisqu'une string est une classe non modifiable, et qu'on n'a passé m_RefStr par référence à personne depuis qu'on lui a assigné une valeur.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. [VBA] Ajouter dynamiquement une référence
    Par jpharand dans le forum VBA Access
    Réponses: 23
    Dernier message: 16/04/2010, 23h28
  2. Comment avoir une référence sur une Vue
    Par Philippe299 dans le forum MFC
    Réponses: 1
    Dernier message: 12/08/2005, 10h03
  3. Comment stocker une référence vers un TTreeNode ds un DFM ?
    Par phplive dans le forum Composants VCL
    Réponses: 1
    Dernier message: 19/07/2005, 12h33
  4. [SOAP][Web Service] erreur création d'une référence Web
    Par Maximil ian dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 20/06/2005, 13h29
  5. Une référence à un élément de sa propre table
    Par szdavid dans le forum Langage SQL
    Réponses: 7
    Dernier message: 29/06/2004, 10h46

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