Comment puis-je utiliser une DLL COM avec la fonction LoadLibrary en C++
Tout d'abord, COM, c'est comme de la magie noire pour moi. Mais j'ai besoin d'utiliser dll COM dans un projet, je suis en train de travailler sur.
J'ai une DLL je développe et j'ai besoin de certaines fonctionnalités qui sont disponibles dans une autre DLL COM. Quand je regarde à la DLL COM avec Depends.exe je vois des méthodes comme DllGetClassObject() et d'autres fonctions, mais aucun de ces fonctions, je suis intéressé.
J'ai accès à la DLL COM (ancien) du code source, mais c'est un gâchis, et je serais plutôt du genre à utiliser la DLL COM en binaire comme une grosse boîte noire ne sachant pas ce qui se passe à l'intérieur.
Alors, comment puis-je appeler la COM des fonctions de la DLL à partir de mon code à l'aide de la fonction LoadLibrary? Est-il possible? Si oui, pourriez-vous me donner un exemple de comment le faire?
Je suis à l'aide de Visual Studio 6 pour ce projet.
Merci beaucoup!
OriginalL'auteur Etienne Savard | 2010-02-02
Vous devez vous connecter pour publier un commentaire.
Vous utilisez généralement
CoCreateInstance()
pour instancier un objet à partir d'une DLL COM. Lorsque vous faites cela, il n'y a pas besoin de charger la DLL premier et obtenir proc adresses comme vous devez le faire avec une DLL. C'est parce que Windows "connaît" les types qui une DLL COM met en œuvre, ce qui DLL ils sont mis en œuvre, et la façon de les instancier. (En supposant bien sûr que la DLL COM est enregistré, il est généralement).Supposons que vous avez une DLL COM avec le IDog interface que vous souhaitez utiliser. Dans ce cas,
chien.idl
myCode.cpp
Toute cette gestion de la mémoire des choses peut être assez crasseux, bien que, et l'ATL fournit des pointeurs intelligents qui rendent la tâche de l'instanciation & la gestion de ces objets un peu plus facile:
EDIT:
Quand j'ai dit ci-dessus que:
...J'ai vraiment passe exactement comment Windows le sait. C'est pas de la magie, bien que cela peut sembler un peu occulte-ish au premier.
COM bibliothèques venir avec les Bibliothèques de types, qui liste les Interfaces et les CoClasses la bibliothèque. Ce Type de Bibliothèque est sous la forme d'un fichier présent sur votre disque dur -- très souvent, il est directement intégré dans la même DLL ou EXE que la bibliothèque elle-même. Windows sait où trouver le Type de Bibliothèque et de la Bibliothèque COM elle-même en regardant dans le Registre de Windows. Les entrées dans le Registre dire à Windows où sur le disque dur se trouve la DLL.
Lorsque vous appelez
CoCreateInstance
, Windows recherche le clsid dans le Registre de Windows, trouve la DLL correspondante, à la charge, et exécute le code approprié dans la DLL qui implémente l'objet COM.Comment obtenir cette information dans le Registre Windows? Lorsqu'une DLL COM est installé, il est inscrit. Ceci est habituellement fait en cours d'exécution regsvr32.exe, qui à son tour en charge de votre DLL en mémoire et appelle une fonction nommée
DllRegisterServer
. Cette fonction, mis en œuvre dans votre serveur COM, ajoute la nécessaire les informations dans le Registre. Si vous utilisez ATL ou d'une autre COM-cadre, c'est probablement effectuée sous le capot, de sorte que vous n'avez pas d'interface directement avec le Registre.DllRegisterServer
ne doit être appelé qu'une seule fois, lors de l'installation en temps.Si vous essayez d'appeler
CoCreateInstance
d'un objet COM qui n'a pas encore été enregistrés par le biais de laregsvr32
/DllRegisterServer
processus, puisCoCreateInstance
échoue avec un message d'erreur qui dit:Heureusement, la solution pour cela est de simplement appeler
regsvr32
sur votre serveur COM, puis essayez de nouveau.COM DLL d'inscription n'est pas automatique, et si c'est un home-grown DLL étape peut avoir été oubliée. Dans ce cas CoCreateInstance serait un échec. Vous devez aborder que dans la réponse quelque part.
Bonne suggestion, édité. Vous avez vraiment creusé un ancien, ici. 🙂
Je n'ai pas le déterrer, de l'activité par un newbie clueless le ramena à la liste Active. Bon résumé sur l'enregistrement d'une DLL.
OriginalL'auteur John Dibling
En général, vous devriez préférer
CoCreateInstance
ouCoGetClassObject
plutôt que l'accès àDllGetClassObject
directement. Mais si vous avez affaire à une DLL que vous ne pouvez ou ne voulez pas, l'enregistrer, puis le ci-dessous décrit (une partie de) ce que ces fonctions ne les coulisses.Donné une CLSID,
DllGetClassObject
vous permet d'obtenir la classe de l'objet, à partir de laquelle vous pouvez créer des instances (via leIClassFactory
interface, si je me souviens bien).Résumé des étapes (il a été un moment depuis que j'ai touché en dernier COM, pour pardonner les erreurs évidentes):
DllGetClassObject(clsid, IID_IClassFactory, &cf)
, oùclsid
est le CLSID vous voulez obtenir la classe de l'objet, etcf
est bien sûr la fabrique de classe.cf->CreateInstance(0, iid, &obj)
, oùiid
est l'IID de l'interface que vous souhaitez utiliser, etobj
est bien sûr l'objet.(
CoCreateInstance
effectue les étapes 1 et 2.CoGetClassObject
effectue l'étape 1. Vous utilisezCoGetClassObject
si vous avez besoin de créer plusieurs instances de la même classe, de sorte que, étape 1 n'a pas besoin d'être répétée à chaque fois.)Est-il une raison que vous recommander de l'appel de la exporté
DllGetClassObject()
directement au lieu d'utiliser la fonction COMCoGetClassObject()
? Il semble comme une... une approche non conventionnelle de moi.le truc avec ce qu est il n'est pas clair si l'OP veut réellement faire, ou s'il est tout nouveau pour COM, veut utiliser un fichier DLL COM, et mentionne LoadLibrary parce que c'est tout ce qu'ils sont familiers avec le fait d'avoir utilisé de la plaine Win32 Dll avant. L'ajout d'un convenable avertissement en haut de la réponse ("Utilisation CoCreate, mais si vous ne pouvez pas, par exemple parce que vous avez besoin de X, alors...") est souvent l'approche la plus sûre à utiliser, en particulier si la réponse est quelque chose que vous ne serait généralement pas faire vous-même, sinon l'OP ou un lecteur occasionnel qui a trouvé via la recherche peut prendre pour une approche recommandée.
Bon point. J'ai ajouté un tel avertissement, avec quelques explications de ce que les fonctions que devrait réellement faire (moins le modèle de thread de contrôle des choses).
Merci, c'est vraiment utile parce que je voulais un moyen de déboguer une extension du shell (IThumbnailProvider) sans avoir à réenregistrer le fichier dll après chaque compilation changement.
OriginalL'auteur Chris Jester-Young
Vous de ne pas utiliser directement la fonction LoadLibrary() avec une bibliothèque COM. CoCreateInstance() va appeler cette fonction si elle ne l'est pas déjà, puis une nouvelle instance de la classe en cours de mise en œuvre de la bibliothèque sur le tas et enfin de retour pour vous raw d'un pointeur vers cet objet. Bien sûr, il risque d'échouer au cours du processus, et donc d'un mécanisme permettant de vérifier l'état comme HRESULT.
Pour la simplicité de son utilisation, vous pouvez penser à une bibliothèque COM commun avec DLL 1) quelques modes d'entrée(principale) de fonction, 2) vous devez appeler certaines fonctions prédéfinies comme CoCreateInstance() pour y entrer, et d'accepter que c'est comme ça parce qu'il a pour.
OriginalL'auteur t.g.
Si la bibliothèque de type est incorporé dans la DLL, vous pouvez l'importer dans votre projet:
Cela permettra de générer automatiquement des fichiers d'en-tête qui sont incluses dans votre projet et vous permettre d'utiliser les objets à exporter.
OriginalL'auteur Luke
Voici un peu de code montrant comment obtenir la fabrique de classe et l'utiliser pour créer un objet COM. Il utilise une structure de garder une trace de la poignée du module et DllGetClassObject pointeur de fonction. Vous devez appuyer sur la poignée du module jusqu'à ce que vous avez fait l'objet COM.
Pour utiliser cette fonction, vous devez allouer une instance de la ComModuleInfo struct et définir la szDLL pour le nom de fichier DLL ou un nom de chemin complet. Puis d'appeler la fonction avec l'id de classe et d'interface Id de l'objet COM vous voulez obtenir à partir de cette DLL.
OriginalL'auteur John Knoeller
Si c'est une DLL COM, tout ce que vous devez faire est d'ajouter une référence à votre projet, et puis vous pouvez appeler les fonctions qui sont dans la DLL.
Oui, vous pouvez utiliser le faible niveau des fonctions COM comme DLLGetClassObject, mais pourquoi le feriez-vous?
Pourquoi auriez-vous une DLL COM qui n'est pas inscrit? Cela semble TRÈS peu probable...
Sur XP et versions ultérieures, vous pouvez utiliser des fichiers de manifeste pour accéder à un non COM DLL
COM enregistré les objets peuvent être utilisés par vos concurrents. Beaucoup d'entreprises pensent que c'est une mauvaise chose.
OriginalL'auteur Greg