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 :

convertir gcroot<String^> en String^%


Sujet :

C++/CLI

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre tr�s actif

    Profil pro
    �tudiant
    Inscrit en
    D�cembre 2004
    Messages
    499
    D�tails du profil
    Informations personnelles :
    �ge : 39
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : D�cembre 2004
    Messages : 499
    Par d�faut convertir gcroot<String^> en String^%
    Salut,

    S�mantiquement le but est de faire �a :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <gcroot.h>
     
    void Test (String ^% k) {
    	k = "apres";
    }
    int main(array<System::String ^> ^args)
    {
    	gcroot<String^> ungcroot = "avant";
    	Test(ungcroot);
            String ^res = ungcroot; // res == "apres"
            return 0;
    }
    Sauf que �a ne fonctionne pas.
    La solution que j'ai trouv�e :

    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
     
    #include <gcroot.h>
    template <typename T> union Dummy {
       // pour récupérer le champ caché _handle de la structure gcroot
    	gcroot<T>& g;
    	void *ptr;
    	Dummy(gcroot<T>& g) : g(g) {}
    };
    template <typename T> T% Gcroot2TrackingReference(gcroot<T>& x) {
    	Dummy<T> d(x);
            /// x est un pointeur sur gcroot,
            /// un gcroot est un pointeur sur Object^
    	return **(T**) d.ptr; // d'où ce cast 
    }
     
    void Test (String ^% k) {
    	k = "apres";
    }
    int main(array<System::String ^> ^args)
    {
    	gcroot<String^> s = "avant";
    	Test(Gcroot2TrackingReference(s));
    	String^ res = s; // res == "apres"
            return 0; 
    }
    Une autre solution ?

    Je peux argumenter sur le fait que c'est 100% safe de faire �a avec l'impl�mentation actuelle de la CLR :

    • un Object ^ est un pointeur dont l'emplacement (l'adresse) est toujours connue de la CLR, qui modifiera sa valeur si elle le souhaite avec ses histoires de d�placement d'objets dans le tas manag�. Seules les fonctions __clrcall peuvent mettre un Object^ sur la pile C++ habituelle : la CLR sait retrouver toutes les fonctions __clrcall de la callstack.
    • un Object^% est une r�f�rence sur Object^ donc c'est l'adresse d'un Object^. Deux cas se pr�sentent : le Object^ est sur la pile C++ et ne bougera pas, le Object^% est alors une r�f�rence C++ normale. Ou bien le Object^ est un champ d'un objet manag�, et alors Object^% est une tracking r�f�rence. La CLR n'a pas de raison de pr�sumer d'o� est la pile C++. Elle sait juste reconna�tre quand une adresse est dans le tas manag� ou non. Un Object^% peut lui �tre situ� n'importe o�, et l'Object^ r�f�renc� �galement (alors que l'Object lui est forc�ment dans le tas manag�).
    • un gcroot est un pointeur sur Object^, Object^ qui lui est situ� � un emplacement (plus ou moins allou� dynamiquement) connu de la CLR.
      le gcroot peut �tre situ� n'importe o�, comme un Object^%.
    • La seule diff�rence entre un gcroot et une tracking reference c'est qu'un gcroot pointe toujours sur un Object^ situ� dans cet emplacement connu de la CLR et allou� dynamiquement, alors qu'une tracking r�f�rence pointe sur un Object^ situ� n'importe o�.
    • Donc caster un gcroot en Object^% n'est pas unsafe. L'inverse l'est peut-�tre.

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par d�faut
    J'ai eu une id�e pour le faire avec un objet interm�diaire (enfin, deux):
    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
    template<class T>
    class GCRootRef
    {
    public: //Note: J'ai une MethodAccessException si c'est private
    	ref class RefHolder
    	{
    	public:
    		T obj;
    	};
    private:
    	gcroot<T>& rs;
    	gcroot<RefHolder^> holder;
    public:
    	GCRootRef(gcroot<T>& rs) : rs(rs), holder(gcnew RefHolder)
    	{
    		holder->obj = rs;
    	}
    	~GCRootRef()
    	{
    		rs = holder->obj;
    	}
    	operator T%() { return holder->obj; }
    };
     
     
    void FonctionRef(System::String^% strref)
    {
    	strref = L"world";
    }
     
    void FonctionTest(void)
    {
    	gcroot<System::String^> str = L"Hello";
    	FonctionRef(GCRootRef<System::String^>(str));
    	System::Console::WriteLine(str);
    }
    Bien s�r, �a n'offre pas vraiment une r�f�rence vers le gcroot, seulement une r�f�rence vers un pointeur manag� dont la modification sera r�percut�e sur l'original.
    D'apr�s Stack Overflow, il n'y a pas de probl�me de dur�e de vie.
    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.

Discussions similaires

  1. [2.0] Convertir une cle primaire byte[] en string
    Par freddyboy dans le forum Acc�s aux donn�es
    R�ponses: 14
    Dernier message: 20/12/2010, 12h05
  2. Convertir et formater un Double en String
    Par Faiche dans le forum D�buter avec Java
    R�ponses: 3
    Dernier message: 25/06/2009, 14h48
  3. R�ponses: 15
    Dernier message: 30/09/2008, 14h43
  4. Convertir un flux ascii pour un String
    Par bubulemaster dans le forum D�buter
    R�ponses: 1
    Dernier message: 24/04/2008, 13h31
  5. [VB.Net] Comment convertir SqlDataReader.GetValues en tableau de string ?
    Par Angath dans le forum Acc�s aux donn�es
    R�ponses: 4
    Dernier message: 13/07/2006, 11h23

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