2010-08-06 3 views
0

J'ai une DLL et un programme, tous deux écrits avec Delphi 2007. Le programme passe une interface, qui descend de IInterface et n'a pas de GUID (donc pas de COM ici) à la DLL qui le stocke pour une utilisation ultérieure.Puis-je passer une interface (IInterface) à une DLL?

Cela semble fonctionner correctement mais parfois je reçois des violations d'accès lorsque le programme est fermé et la DLL est déchargée. Je ne suis pas sûr de la raison de ces AVs. Il est possible que l'interface soit hors de portée et que, par référence, l'objet sous-jacent, qui réside dans le contexte du programme, soit libéré, causant une corruption de mémoire car deux gestionnaires de mémoire différents sont impliqués.

Je n'utilise pas sharemem et je ne veux pas pour diverses raisons (l'une étant que d'autres programmes qui ne sont pas écrits en Delphi pourraient vouloir utiliser cette DLL).

Je sais que je ne devrais pas passer des chaînes, des tableaux ouverts et des objets de cette manière, mais les interfaces devraient-elles fonctionner?

Répondre

2

Oui, cela devrait fonctionner correctement si tout est Delphi. Vous devez vous assurer de compiler les deux si l'interface change. Les compilateurs C++ semblent être compatibles, mais attention aux autres compilateurs.

Normalement, un compte de référence atteignant zéro amène le créateur de l'objet à le libérer. Aucun problème dans les différents gestionnaires de mémoire là-bas.

Ce qui pourrait être le problème est que votre DLL a toujours une référence à un objet via une interface et appelle IUnknown.Release pour réduire le nombre de références quand il n'en a plus besoin. Si, pour une raison quelconque, l'objet référencé est déjà libéré, vous obtiendrez des AV. Assurez-vous que toutes les références (vérifiez les variables globales) aux objets via les références sont supprimées avant de fermer l'application.

Les options de débogage de FastMM peuvent vous aider à trouver votre problème.

0

Il n'y a rien de mal à passer des interfaces vers et depuis les DLL. C'est exactement ce que vous faites chaque fois que vous utilisez une interface de l'API Windows, après tout. Par conséquent, votre problème est plus profond.

L'absence d'un GUID est un problème simple à résoudre. Appuyez simplement sur Ctrl + Maj + G. Ensuite, vous n'avez aucun obstacle à l'utilisation de COM. Toutes les choses liées à l'interface dans Delphi deviennent plus faciles lorsque vos interfaces ont des GUID, même lorsque vous n'utilisez pas COM.

Si votre DLL était une DLL COM, le programme hôte serait en mesure de vérifier s'il est encore possible de décharger la DLL. La structure COM de Delphi conserve automatiquement la trace de l'existence d'objets actifs de cette DLL. Lorsque l'hôte souhaite décharger la DLL, il demande à la DLL si c'est sûr à faire.

Votre objet doit être un objet COM. Le programme hôte crée des instances de votre objet avec la fonction CoCreateInstance standard du système d'exploitation, en utilisant le GUID de votre objet. Votre DLL sera déjà enregistrée avec le système d'exploitation, donc CoCreateInstance saura automatiquement charger votre DLL et appeler les bonnes fonctions afin d'instancier votre classe. (Si vous écrivez l'hôte aussi, utilisez simplement la fonction CreateComObject de Delphi.)

+0

Désolé, je voulais écrire GUID plutôt que GUI. Bien sûr, ne pas avoir une interface graphique ne m'empêche pas d'utiliser COM, mais j'ai des interfaces sans GUID. – dummzeuch

+0

Ah, ça a plus de sens. J'ai mis à jour ma réponse en conséquence. –

Questions connexes