2009-06-24 7 views
1

Supposons que vous procédiez comme suit:Les objets COM sont-ils responsables de conserver leur propre module en mémoire?

1) Chargez foo.dll à l'aide de LoadLibrary.

2) Obtenir un pointeur sur une fonction en utilisant GetProcAddress.

3) Invoquer la fonction, en vous donnant une référence à un objet COM implémenté dans ce module.

4) Gratuit foo.dll en appelant FreeLibrary.

5) Appelez une méthode sur l'objet COM.

Voulez-vous que l'étape 5 réussisse et ne fonctionne pas? En d'autres termes, l'objet COM est-il lui-même chargé d'appeler LoadLibrary (à nouveau) pour incrémenter le nombre de références que Windows conserve pour chaque module, garantissant ainsi qu'il ne survit pas au module?

Répondre

2

Je m'attendrais à un AV. Même si ça n'a pas été le cas aujourd'hui, c'est probablement un accident qui attend de se produire. Pour un cas comme celui-ci, où un objet COM est renvoyé via une exportation DLL personnalisée, l'objet COM ne doit pas incrémenter le nombre de références de la DLL - tant que l'application utilise des ressources d'une DLL, elle explicitement chargé, il incombe à l'application de conserver cette DLL chargée.

Pour les objets COM in-proc créés via la route CoCreateInstance normale, la DLL exportera généralement DllCanUnloadNow, qui doit renvoyer S_FALSE tant qu'il existe des références en attente.

Cependant, rien n'empêche l'objet COM d'incrémenter le compte de référence de la DLL via LoadLibrary - il n'y a rien d'illégal ou dangereux à faire.

+0

Comment la DLL suit-elle les références en suspens en ce qui concerne l'appel DllCanUnloadNow? Merci! –

+0

Cependant, il veut. où le constructeur/destructeur pour chaque objet COM incrémente/décrémente un nombre de références globales pour le module, et DllCanUnloadNow vérifie juste ce compte ref. – Michael

4

Certainement pas. Le nombre de références du module est maintenu par les méthodes normales d'utilisation - ce que vous faites est une porte dérobée dans le schéma d'exécution. Normalement, vous utilisez CoCreateInstance et ainsi de suite pour créer vos objets - ce sont des wrapper qui appellent CoGetClassObject et DllGetClassObject. CoGetClassObject appelle CoLoadLibrary qui maintient un compte de référence sur la DLL. En outre, vous pouvez appeler LockServer sur l'objet de classe pour maintenir un nombre de références sur l'objet de classe pour les performances, mais cela n'est pas nécessaire pour s'assurer que la DLL reste chargée.

+0

Très intéressant. Est-ce que la réponse change si nous disons que la fonction appelée à l'étape 3 s'appelle MyCreateInstance? C'est à dire. il est modélisé après CoCreateInstance? Merci! –

+0

Non. Dans la version "standard" ci-dessus, l'appel CoLoadLibrary maintient la référence à la DLL - ce sera publié seulement quand il est sûr de le faire (en regardant les références en direct aux objets créés dans le serveur COM, ou l'événement que CoUninitialize est appelé Dans votre version, vous devez vous assurer que vous le faites vous-même –

Questions connexes