pma3d
Messages postés36Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention14 septembre 2005
-
25 août 2005 à 18:00
pma3d
Messages postés36Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention14 septembre 2005
-
30 août 2005 à 17:25
Bonjour,
Je poste ici en ne sachant pas trop où mettre mon problème,
puisque même si je développe un service web, cela n'a rien à voir avec
la catégorie "service web".
Bref, j'ai donc une classe en C++ managé qui encapsule une classe non
managée. La classe managée contient simplement un pointeur vers la
classe non managée :
public __gc class ClasseManagee: public IDisposable
{
public:
// Constructeur
ClasseManagee(void){
m_pThis = new ClasseNonManagee();
}
// Destructeur
~ClasseManagee(void){
delete m_pThis;
// Dispose();
}
protected:
ClasseNonManagee__nogc* m_pThis;
};
Lorsque je lance ceci, j'obtiens une exception NullReferenceException
sur le delete m_pThis. Le problème est que j'ai vérifié en mode debug,
tous mon pointeur est pourtant bien référencé à cet endroit !!! Ca fait
des jours que je recherche des infos, mais je ne trouve rien, alors
j'espère que quelqu'un aura déjà eu ce cas et pourra m'aider à m'en
sortir.
pma3d
Messages postés36Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention14 septembre 2005 30 août 2005 à 17:25
Bon, en fait, j'ai trouvé d'où venait le problème, après quelques jours
de traque, comme vous pouvez le voir à la date de ce post
Donc, ça venait de plus haut, dans mon client web. J'avais un peu trop
simplifié le code donné en exemple en haut, l'erreur venait d'un
constructeur supplémentaire, qui me permettait d'initialiser
directement la valeur du pointeur avec une adresse récupérée
auparavant. A l'époque, je ne pensais pas que ça pouvait venir de là.
J'étais focalisé sur le Garbage Collector dont on ne peut pas maîtriser
le fonctionnement, et là était mon erreur.
Le problème est que plusieurs instances de ClasseManagee étaient
créées, et un certain nombre d'entre elles pointaient vers la même zone
non managée. Une fois la première instance de ClasseManagee libérée, et
donc le pointeur m_pThis allant avec, l'instance suivante avec le même
pointeur ne pouvait pas le libérer. Ceci explique aussi pourquoi le
pointeur contenait bien une valeur, mais la case mémoire pointée avait
déjà été libérée !!! Il m'a suffit de faire en sorte qu'une seule
instance de ClasseManagee soit créée pour une valeur de m_pThis, et le
tour était joué !
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 25 août 2005 à 19:11
Peut être Dispose qui passe avant le destructeur ? En MC++ je sais pas trop mais normalement tu devrais deleter le pointeur dans Dispose et le destructeur devrait appeler Dispose, utilises GC.SuppressFinalize dans Dispose.
pma3d
Messages postés36Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention14 septembre 2005 25 août 2005 à 21:01
Alors, pour le nogc, effectivement, il est implicite, et par
conséquent, sa présence ou son absence n'ont absolument aucun effet. Il
est là juste pour la clarté.
Pour le Dispose, en fait, il est en commentaire, c'est un reste que j'avais utilisé suite aux instructions données sur la msdn.
J'ai essayé de faire exactement comme ils le disent, c'est-à-dire,
comme tu le précises, de mettre le delete dans la méthode Dispose, ce
qui apparemment permettrait de laisser décider au Garbage collector du
moment adéquat pour l'effectuer. La solution proposée ne marche pas
(d'ailleurs, je ne serais pas là dans le cas contraire )...
Mais, là où tu m'intéresses, c'est avec la méthode SuppressFinalize().
En effet, j'ai déjà essayé à tout hasard de l'utiliser pour empêcher le
GC de finaliser ma classe managée, et donc, si j'ai bien, d'appeler le
destructeur, mais ça ne marchait pas non plus. Que veux-tu dire par
utiliser SuppressFinalize dans Dispose? Tu veux dire sur mon pointeur
non managé ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Lutinore
Messages postés3246Date d'inscriptionlundi 25 avril 2005StatutMembreDernière intervention27 octobre 201241 26 août 2005 à 00:18
C'est exactement comme ca que Microsoft propose de "wrapper" une classe non managée, donc je ne sais pas désolé. Pour ce qui est de la méthode Dispose et SuppressFinalize le meilleur moyen de l'implementer de manière robuste c'est de respecter ce modèle:
pma3d
Messages postés36Date d'inscriptionlundi 13 juin 2005StatutMembreDernière intervention14 septembre 2005 26 août 2005 à 10:18
Merci pour le lien, je n'avais pas pensé à chercher des infos sur la
méthode dispose, et c'est effectivement intéressant. En fait, le lien
dont je te parlais était celui ci :