2008-09-15 5 views
1

Je suis confronté à un problème complexe avec un contrôle ActiveX que j'écris - parfois, Internet Explorer semble ne pas réussir à décharger correctement le contrôle lors de l'arrêt du processus. Le destructeur de l'instance de contrôle n'est donc pas appelé. Le contrôle est écrit en C++, utilise ATL et est compilé à l'aide de Visual Studio 2005. Le destructeur de l'instance de contrôle est toujours appelé lorsque l'utilisateur quitte la page dans laquelle le contrôle est incorporé - le problème se produit uniquement lorsque le navigateur est fermé. Lorsque j'exécute IE sous un débogueur, je ne vois rien d'inhabituel - le débogueur n'attrape aucune exception, violation d'accès ou échec d'assertion, mais le problème est toujours là - je peux définir un point d'arrêt dans le contrôle destructeur et il n'est jamais touché quand je ferme le broswer.Dans quelles circonstances Internet Explorer ne parvient-il pas à décharger correctement un contrôle ActiveX?

En outre, lorsque je charge une simple page HTML qui intègre plusieurs instances du contrôle, je ne vois pas le problème. Le problème ne semble se produire que lorsque le contrôle est instancié à partir de notre application web, qui insère des balises dynamiquement dans la page Web - bien sûr, ne sachant pas ce qui cause ce problème, je ne sais pas si cette information est pertinente ou non. mais cela semble indiquer que cela pourrait être un problème d'IE, car cela dépend des données.

Quand je lance l'exemple simple de test sous le débogueur, je peux mettre un point d'arrêt dans le destructor du contrôle et il est touché chaque fois. Je crois que cela exclut un problème avec le contrôle lui-même (par exemple, une erreur qui empêcherait le destructeur d'être appelé, comme une fuite d'interface.)

Je fais la plupart de mes tests avec IE 6, mais j'ai vu le problème se produire sur IE 7, aussi bien. Je ne l'ai pas testé IE 8.

Mon hypothèse de travail est en ce moment qu'il ya quelque chose dans le code HTML dynamique qui provoque le navigateur pour fuir une interface sur le contrôle ActiveX. Jusqu'à présent, je n'ai pas été capable de produire un bon cas de test qui reproduit cela en dehors de l'application, et l'application est un peu trop grande pour faire un bon test.

J'espérais que quelqu'un pourrait être en mesure de donner un aperçu des éventuels bogues IE qui sont connus pour provoquer ce genre de comportement. Soit dit en passant, la réponse fournie ci-dessous est trop générale - je suis à la recherche d'un ensemble spécifique de circonstances connues pour causer cela. Sûrement quelqu'un là-bas a déjà vu ça.

Répondre

3

Pour déboguer un problème dans COM avec C++ où le destructeur (C++) d'un objet n'est pas appelé, la meilleure approche consiste à se concentrer sur l'incrémentation ou la décrémentation des ré-comptes de l'objet COM. Ce qui se passe probablement, c'est que quelqu'un incrémente le refcount une fois de trop, et ensuite ne le décrémente pas le même nombre de fois. Cela conduit à l'objet n'est pas libéré.

Il est possible que votre HTML dynamique est tout simplement montrer un bug dans IE, ce qui ne se produit pas si vous utilisez une page statique. S'il y a un bogue dans IE, l'astuce serait de comprendre ce qui provoque l'apparition du bug, et ce que vous pouvez faire pour tromper IE en libérant votre objet COM correctement (comme, faire disparaître le HTML).

+0

Merci pour les suggestions. Le code HTML dynamique est suffisamment velu pour que personne ne sache exactement comment cela fonctionne, et mes tentatives pour le démêler juste assez pour créer un cas de test reproduisant le problème ont échoué jusqu'à présent. –

0

Une autre approche - ajouter du code de nettoyage à votre fonction DllMain (en ajoutant cette fonction si elle n'existe pas déjà).Ensuite, peu importe compte de référence (et les erreurs de comptage de référence), lorsque votre DLL est déchargé, vous pouvez vous nettoyer:

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) { 
    if (dwReason == DLL_PROCESS_DETACH) { 
     CleanUpAnyObjectsStillAlive(); 
    } 
} 

Oh, et un mot d'avertissement - ne faire prendre pas trop longtemps votre nettoyage - si vous fais, je ne peux pas promettre que l'arrêt du processus ne te tuera pas de toute façon.

+0

Vous vous rendez compte que dans un contrôle écrit en MFC ne peut pas faire cela, non? –

+0

Pourquoi? Je ne suis pas un expert MFC, mais je ne vois pas comment une bibliothèque comme MFC pourrait vous empêcher de fournir votre propre DllMain si vous voulez en inclure un. Voulez-vous dire que les contrôles MFC ne fournissent pas un moyen de les nettoyer? Surprenant si le cas. – Bruce

+0

Ou peut-être que vous voulez dire MFC fournit sa propre implémentation de DllMain, et ne vous permet pas de vous y connecter? Ce serait un problème. – Bruce

0

J'ai le même problème, mais seulement sur un ordinateur spécifique. Cet ordinateur a également un problème avec Flash ActiveX, qui reste actif après la fermeture de l'onglet. Ma conjecture est que le problème n'est pas avec votre code. Avez-vous ce problème sur d'autres ordinateurs?

+0

J'ai déjà vu ça sur d'autres machines. –

Questions connexes