2010-02-25 6 views
2

Quelle est la différence entre les deux lignes de code ci-dessous:COM Object Clean Up

CComPtr<IInterface> m_interface; 

IInterface* m_interface; 

Je sais que CComPtr aider à éliminer les fuites de mémoire, mais je reçois des résultats incohérents. Lors de la déclaration du pointeur avec CComPtr<IInterface> m_interface; et en utilisant l'interface dans mon code C# il n'y a pas d'erreurs, mais en utilisant l'interface dans VC++, j'obtiens une erreur d'exception non gérée, même si je commente la création d'instance de IInterface.

Je suis assez sûr que le problème est ici quelque part:

STDMETHODIMP CSomeClass::get_IClass(IClass** var) 
{ 
     return m_class_var->QueryInterface(var); 
} 
STDMETHODIMP CSomeClass::putref_IClass(IClass* var) 
{ 
    m_class_var = var; 
    return S_OK; 
} 

Lorsque je déclare le pointeur d'interface avec: IInterface* m_interface; -je obtenir une erreur de RPC_E_SERVERFAULT lors du test de l'interface en C# et doivent appeler explicitement GC. Collect() pour éviter que l'erreur ne soit lancée après l'instanciation de quelques objets. Lors du test de l'interface dans VC++, l'erreur est cohérente mais lorsqu'elle se produit est différente. Si je commente la création d'instance de IInterface le code fonctionne bien, cependant quand j'essaye de créer une instance je reçois la même erreur qu'avant, juste une erreur d'exception vague non gérée. Qu'est-ce que je fais mal ici?

+0

Vous devriez vraiment passer 15 minutes élaboration d'un extrait très court qui démontrerait le problème. – sharptooth

+0

Vous dites "en utilisant l'interface dans VC++ je reçois une erreur d'exception non gérée" - pouvez-vous nous montrer le code en utilisant l'interface dans VC++? –

Répondre

1

IInstance* m_instance est un simple pointeur vers un objet IInstance. Vous devez gérer vous-même la durée de vie de ce pointeur. Vous n'avez pas new et delete objets COM comme vous les objets ordinaires. Au lieu de cela, le système d'exploitation alloue l'objet lorsque vous appelez la fonction WINAPI `CoCreateInstance »:

// instantiate the CoClass which implements IInstance... 
IInstance* instance = 0; 
HRESULT hr = CoCreateInstance(__uuidof(mylibrary::MyCoClass), 0, CLSCTX_INPROC_SERVER, __uuidof(mylib::IInstance), &instance); 

: : 

// We're done, so release the object... 
instance->Release(); 
instance = 0; 

Chaque objet COM implémente le comptage de référence. Lorsque la dernière référence à un objet a été Release() ed, l'objet COM se détruit lui-même.

L'utilisation de CComPtr<> simplifie la gestion de la durée de vie des objets COM. C'est un pointeur intelligent de la même nature que std :: auto_ptr ou shared_ptr de Boost, mais il fonctionne avec les objets COM. Généralement, lorsque vous utilisez un CComPtr, vous appelez la fonction membre CreateInstance au lieu d'appeler la fonction WINAPI, et vous n'appelez pas explicitement Release lorsque vous avez terminé.Il suffit de laisser le CComPtr hors de portée, et quand il est appelé destructor appellera Release pour vous:

void function() 
{ 
    // instantiate the CoClass which implements IMyInterface... 
    CComPtr<IInstance> instance; 
    instance.CoCreateInstance(__uuidof(mylibrary::MyCoClass)); 

    : : 

    // We're done, so release the object... 
    // dont have to do anything, it will be released when function() exits 
} 
0

CComPtr < IInterface> m_interface est un objet. Alors que IInterface * m_interface est un pointeur.

Le premier aura son destructeur appelé quand il sort de la portée et je pense (depuis longtemps que je l'ai utilisé) il appellera automatiquement m_interface -> Release(). Ce dernier est un pointeur vers une interface et vous devez gérer quand m_interface-> Release() est appelé.

Pouvez-vous confirmer que l'objet COM n'est pas libéré avant l'accès?

+0

Merci. J'ai édité ma question un peu pour donner plus d'informations. J'appelle Release() dans l'implémentation de l'interface de test de code VC++. Cela ne m'aide pas, je suppose que j'ai besoin de libérer/détruire l'objet dans le code non géré même en utilisant CComPtr mais je ne suis pas sûr. –

+0

@Reggie: Parfois, vous devez appeler AddRef/Release sur un objet, même s'il est géré par un CComPtr. Vous aurez besoin de nous montrer le code VC++ afin que nous puissions voir si vous faites quelque chose de mal. –

2

CComPtrCComPtr est un pointeur intelligent conçu pour faire la bonne chose lorsqu'il est utilisé avec des idiomes COM.

Votre code get_IClass semble bon, mais putref_IClass doit appeler AddRef sur la IClass comme vous le stocker. Si vous utilisiez CComPtr, cela arriverait automatiquement.

Vous devrez ajouter plus de détails sur votre exception non gérée VC++.

+0

J'ai un peu édité ma question pour donner plus d'informations. –

+1

Merci. cette aide à comprendre un peu mieux. Je vous voterais mais je n'ai pas assez de points de réputation –