11
votes

Pourquoi la dénincialisation provoque-t-elle une erreur à la sortie?

Je travaille sur une application C ++ pour lire certaines données d'un fichier Excel. Je l'ai travaillé, mais je suis confus d'une partie. Voici le code (simplifié pour ne lire que la première cellule).

void _Release() throw()
{
    if (m_pInterface != NULL) {
        m_pInterface->Release();
    }
}


1 commentaires

AFAIK, il n'y a en fait aucun mal à ne pas appeler de notation dans cette situation car votre processus est de toute façon, de toute façon (semblable à la manière dont il est correct de ne pas libérer de mémoire allouée de manière dynamique, car elle sera libérée lorsque le système d'exploitation nettoie le processus). Mais l'appelant est une bonne habitude d'entrer, car lorsque vous pourriez le faire dans une situation différente lorsque le processus n'est pas sur le point de se terminer.


4 Réponses :


17
votes

Le problème que vous rencontrez est une portée. La réponse courte consiste à déplacer la monnaie et le point de vue en une portée extérieure des PTR. Par exemple: xxx

La réponse plus longue est que les destructeurs PTRS (qui appelle la libération) sont appelés à la sortie de la principale. Ceci est après le conseil qui, fondamentalement, arrête le canal de communication entre votre application et l'objet COM.

Quelles sont les conséquences de ne pas appeler Counit? Pour des serveurs COM de courte durée de traitement, il n'y a vraiment aucune conséquence négative.


1 commentaires

Merci. J'ai vu une suggestion similaire ailleurs, mais l'explication n'a pas eu de sens. Merci de le nettoyer pour moi.



5
votes

Une solution élégante consiste à mettre Coinitializeex et à mettre en savoir-faire dans leur propre classe. Voir cette Article de Raymond Chen .


0 commentaires

2
votes

La signification de Coinitialize est de saisir votre fil dans un appartement; et CounInitialize supprime votre fil de l'appartement.

Utilisation d'un pointeur d'interface Lorsque vous n'êtes pas dans un appartement provoque le problème, car vous n'êtes autorisé à utiliser qu'un pointeur d'interface brut dans l'appartement, il a été créé. (Vous pouvez préserver le pointeur d'interface vers un autre appartement afin d'utiliser dans un autre appartement).

Lorsque vous apportez un appel via le pointeur d'interface et que l'objet réside dans un autre appartement (ce qui est vrai dans ce cas), votre pointeur d'interface effectue des appels dans un objet proxy dans l'appartement qui communique ensuite via RPC avec un talon l'appartement de destination. Si vous aviez quitté l'appartement (en faisant CounInitialize ), ce transport ne sera plus disponible, ce qui entraîne votre erreur.

Si vous utilisez des serveurs en cours de procédure occasionnellement, vous pouvez vous éloigner de faire de la discrétion avant d'appeler la sortie car il n'y a pas de couche de transport impliquée, mais ce n'est pas une bonne idée.

BTW, le deuxième argument à Coinitialize Spécifie si vous souhaitez entrer une STA (c'est-à-dire que votre thread sera le seul fil de votre appartement; et un nouvel appartement est créé lorsque vous le faites), ou le MTA (dont il y en a un par processus).

Les options sont Coinit_ApparmentamentHreaded et COINIT_MULTHILDEADED respectivement; Vous avez spécifié 0 qui est en fait coinit_multhreadheaded . IMHO, il serait plus clair d'utiliser le nom symbolique dans votre code plutôt qu'un nombre magique.


0 commentaires

0
votes

0 n'est pas COINIT_MULTHILDEAD . 0 est Coinit_AppartementHeadheaded . Reportez-vous à https://docs.microsoft.com / FR-US / WINDOWS / WIN32 / API / OBJBASE / NE-OBJBASE-COINIT


2 commentaires

Merci pour la réponse. Si vous répondez à @ m.m, veuillez ajouter cela comme un commentaire sur sa réponse à la place.


Oui John, c'était une réponse à @ m.m mais je ne pouvais pas ajouter comme commentaire que je n'ai pas encore assez de "réputation": - | commenter.