Modifier

Partager via


Questions fréquemment posées sur DLL

Une DLL MFC peut-elle créer plusieurs threads ?

Sauf lors de l'initialisation, une DLL MFC peut créer plusieurs threads en toute sécurité tant qu'elle utilise les fonctions Win32 de stockage local des threads (TLS), telles que TlsAlloc, pour allouer le stockage local des threads. Toutefois, si une DLL MFC utilise __declspec(thread) pour allouer le stockage local des threads, l'application cliente doit être implicitement liée à la DLL. Si l'application cliente établit un lien explicite avec la DLL, l'appel à LoadLibrary n'aboutira pas au chargement de la DLL. Pour plus d'informations sur les variables locales aux threads dans les DLL, voir thread.

Une DLL MFC qui crée un nouveau thread MFC lors du démarrage cessera de répondre lorsqu'elle sera chargée par une application. Ceci inclut chaque fois qu'un threading est créé en appelant AfxBeginThread ou CWinThread::CreateThread à l'intérieur :

  • Le InitInstance d'un objet dérivé CWinApp dans une DLL MFC normale.

  • Une fonction DllMain ou RawDllMain fournie dans une DLL MFC ordinaire.

  • Une fonction DllMain ou RawDllMain fournie dans une DLL d'extension MFC.

Une application multithread peut-elle accéder à une DLL MFC dans différents threads ?

Les applications multithreads peuvent accéder aux DLL MFC régulières qui sont liées dynamiquement au MFC et aux DLL d'extension MFC à partir de différents threads. Une application peut accéder à des DLL MFC normales qui sont liées statiquement au MFC à partir de plusieurs threads créés dans l'application.

Existe-t-il des classes ou des fonctions MFC qui ne peuvent pas être utilisées dans une DLL MFC ?

Les DLL d'extension utilisent la classe CWinApp-dérivée de l'application cliente. Elles ne doivent pas avoir leur propre classe CWinApp-dérivée.

Les DLL MFC ordinaires doivent avoir une classe CWinApp-dérivée et un seul objet de cette classe d'application, tout comme une application MFC. Contrairement à l'objet CWinApp d'une application, l'objet CWinApp de la DLL n'a pas de pompe à message principale.

Notez que le mécanisme CWinApp::Run ne s'appliquant pas à une DLL, l'application est propriétaire de la pompe à messages principale. Si la DLL ouvre des boîtes de dialogue sans modèle ou possède sa propre fenêtre de trame principale, la pompe à message principale de l'application doit appeler une routine exportée par la DLL, qui appelle à son tour la fonction membre CWinApp::PreTranslateMessage de l'objet d'application de la DLL.

Quelles techniques d'optimisation dois-je utiliser pour améliorer les performances de l'application cliente lors du chargement ?

Si votre DLL est une DLL MFC ordinaire liée statiquement à MFC, le fait de la remplacer par une DLL MFC ordinaire liée dynamiquement à MFC réduit la taille du fichier.

Si la DLL comporte un grand nombre de fonctions exportées, utilisez un fichier .def pour exporter les fonctions (au lieu d'utiliser __declspec(dllexport)) et utilisez l'attribut NONAME du fichier .def pour chaque fonction exportée. L'attribut NONAME fait que seule la valeur ordinale et non le nom de la fonction est stockée dans la table d'exportation de la DLL, ce qui réduit la taille du fichier.

Les DLL liées implicitement à une application sont chargées au moment du chargement de l'application. Pour améliorer les performances lors du chargement, essayez de diviser la DLL en plusieurs DLL. Placez toutes les fonctions dont l'application appelante a besoin immédiatement après le chargement dans une DLL et demandez à l'application appelante d'établir un lien implicite avec cette DLL. Placez les autres fonctions dont l'application appelante n'a pas besoin immédiatement dans une autre DLL et demandez à l'application d'établir un lien explicite avec cette DLL. Pour plus d'informations, consultez la section Lier un exécutable à une DLL.

Il y a une fuite de mémoire dans ma DLL MFC normale, mais mon code semble correct. Comment puis-je trouver la fuite de mémoire ?

L'une des causes possibles de la fuite de mémoire est que le MFC crée des objets temporaires qui sont utilisés à l'intérieur des fonctions du gestionnaire de messages. Dans les applications MFC, ces objets temporaires sont automatiquement nettoyés dans la fonction CWinApp::OnIdle() appelée entre deux traitements de messages. Cependant, dans les bibliothèques de liens dynamiques (DLL) MFC, la fonction OnIdle() n'est pas automatiquement appelée. Par conséquent, les objets temporaires ne sont pas automatiquement nettoyés. Pour nettoyer les objets temporaires, la DLL doit appeler explicitement OnIdle(1) périodiquement.