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.