2010-07-20 16 views
4

J'ai une variable membre a déclaré queexception lors de la destruction de CComPtr

CComPtr<IXMLDOMDocument2> m_spXMLDoc; 

document XML est créé comme celui-ci

CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, 
    IID_IXMLDOMDocument2, (void**)&m_spXMLDoc)); 

Maintenant, quand les sorties de l'application, une exception est levée. Callstack pointe vers p->Release()

~CComPtrBase() throw() 
{ 
    if (p) 
     p->Release(); 
} 

Quand je passe la souris sur la p dans débogueur VS, il pointe une mémoire valide.

Les derniers points de callstack à exception dans msxm6

msxml6.dll!3d6cXX03() 

Toutes les suggestions, ce qui pourrait être la raison? Je ne pense pas que ce soit un problème CComPtr.

+0

La libération manuelle() s ou une mauvaise utilisation d'autres CComPtrs (par exemple, via 'Attach()') peut être une raison. Si tout le reste semble correct, il peut également y avoir une corruption de mémoire résultant d'autres problèmes. –

+0

Quelle est la durée de vie de l'objet? Quand le destructeur est-il appelé? –

+0

Avez-vous déjà compris la raison? Je viens de rencontrer un problème similaire (sauf que j'utilise les classes Debug Interface Access SDK COM, mais probablement les classes COM utilisées ne sont pas concernées). Je suspecte que c'est quelque chose lié au bogue d'implémentation de CComPtr ou n'importe quoi. – JavaMan

Répondre

0

Vous devez créer l'instance en utilisant les fonctions membres de CComPtr:

m_spXMLDoc.CoCreateInstance(...) 
0

Je suis à la recherche d'un problème similaire où le serveur IExplorer rips com pour la page Web actuelle sous les clients.
Le résultat semble être cette version ne peut pas être effectuée, à la place vous obtenez des erreurs com comme le serveur a des clients déconnectés.

1

Faites ceci avant que votre programme:

if(m_spXMLDoc.p) 
    m_spXMLDoc.Release(); 

J'ai vu ceci avant moi-même. Le problème est lié au comptage des références (évidemment), mais je n'ai jamais cherché à en trouver la raison. J'espère que cela t'aides!

5

J'ai eu un problème similaire et finalement j'ai trouvé que c'était juste un bug. Je dois m'assurer que CoUninitialize() est appelé APRÈS que le CComPtr est détruit. Sinon, il y aura une exception.

int _tmain(int argc, _TCHAR* argv[]) { 
    CoInitialize(NULL); 
    mymain(); 
    //put all logic in a separate function so that CComPtr 
    //is destructed before CoUninitialize() 
    CoUninitialize(); 
    return 0; 
} 

Déclarant CComPt r dans la même fonction que l'appel CoUninitialize() provoquera l'exception car la destruction se produit après que la fonction se termine.

+0

Une alternative est de mettre le code déclarant un en utilisant le 'CComPtr' dans un bloc imbriqué. Une autre alternative est d'appeler manuellement 'CComPtr :: Release()'. Les deux vont résoudre exactement le même problème, juste un peu différemment. – sharptooth