Eti*_*ard 7 c++ com dll loadlibrary visual-c++
首先,COM对我来说就像是黑魔法.但我需要在我正在开发的一个项目中使用COM dll.
所以,我有一个我正在开发的DLL,我需要一些单独的COM DLL中可用的功能.当我使用Depends.exe查看COM DLL时,我看到像DllGetClassObject()这样的方法和其他函数,但没有我感兴趣的函数.
我可以访问COM DLL(遗留)源代码,但它很乱,我更喜欢使用二进制中的COM DLL,就像一个大黑盒子,不知道里面发生了什么.
那么,如何使用LoadLibrary从我的代码中调用COM DLL函数?可能吗?如果,是的,你能给我一个如何做的例子吗?
我正在使用Visual Studio 6进行此项目.
非常感谢!
Chr*_*ung 22
一般来说,您应该更喜欢CoCreateInstance或CoGetClassObject不是DllGetClassObject直接访问.但是,如果你正在处理一个你不能或不想注册的DLL,那么下面描述(部分)这些功能在幕后做什么.
给定一个CLSID,DllGetClassObject允许您获取类对象,您可以从中创建实例(通过IClassFactory接口,如果我没记错的话).
步骤摘要(自从我上次触摸COM以来已经有一段时间了,所以原谅任何明显的错误):
DllGetClassObject(clsid, IID_IClassFactory, &cf),clsid您想要获取类对象的CLSID 在哪里cf,当然是类工厂.cf->CreateInstance(0, iid, &obj),iid您想要使用的接口的IID 在哪里obj,当然是对象.(CoCreateInstance执行步骤1和步骤2. CoGetClassObject执行步骤1. CoGetClassObject如果需要创建同一类的多个实例,则可以使用,因此每次都不需要重复步骤1.)
Joh*_*ing 11
通常,您将使用CoCreateInstance()从COM DLL实例化对象.当你这样做时,不需要首先加载DLL并获得proc地址,就像你需要使用普通的DLL一样.这是因为Windows"知道"COM DLL实现的类型,它们实现了什么DLL,以及如何实例化它们.(当然假设COM DLL已经注册,通常是这样).
假设您有一个带有要使用的IDog接口的COM DLL.在这种情况下,
interface IDog : IUnknown
{
HRESULT Bark();
};
coclass Dog
{
[default] Interface IDog;
};
Run Code Online (Sandbox Code Playgroud)
IDog* piDog = 0;
CoCreateInstance(CLSID_DOG, 0, CLSCTX_INPROC_SERVER, IID_IDOG, &piDog); // windows will instantiate the IDog object and place the pointer to it in piDog
piDog->Bark(); // do stuff
piDog->Release(); // were done with it now
piDog = 0; // no need to delete it -- COM objects generally delete themselves
Run Code Online (Sandbox Code Playgroud)
但是,所有这些内存管理的东西都会变得相当蹩脚,并且ATL提供了智能指针,使得实例化和管理这些对象的任务变得更加容易:
CComPtr<IDog> dog;
dog.CoCreateInstance(CLSID_DOG);
dog->Bark();
Run Code Online (Sandbox Code Playgroud)
当我在上面说:
Windows"知道"COM DLL实现的类型[和]它们实现的DLL
...我真的很清楚Windows如何知道这一点.这不是魔术,虽然起初可能看起来有些神秘.
COM库附带了类型库,它列出了库提供的接口和CoClasses.此类型库采用硬盘驱动器上的文件形式 - 通常它直接嵌入到与库本身相同的DLL或EXE中.Windows通过查看Windows注册表知道在哪里可以找到类型库和COM库本身.注册表中的条目告诉Windows DLL所在的硬盘驱动器上的位置.
当您调用时CoCreateInstance,Windows在Windows注册表中查找clsid,找到相应的DLL,加载它,并在实现COM对象的DLL中执行正确的代码.
这些信息如何进入Windows注册表?安装COM DLL时,它已注册.这通常通过运行regsvr32.exe来完成,后者又将DLL加载到内存中并调用名为的函数DllRegisterServer.在COM服务器中实现的该功能将必要信息添加到注册表中.如果您正在使用ATL或其他COM框架,这可能是在引擎盖下完成的,这样您就不必直接与注册表连接. DllRegisterServer只需要在安装时调用一次.
如果您尝试调用CoCreateInstance尚未通过regsvr32/ DllRegisterServerprocess 注册的COM对象,CoCreateInstance则会因以下错误而失败:
类未注册
幸运的是,解决此问题的方法是简单地调用regsvr32COM服务器,然后再试一次.
您不直接将LoadLibrary()与COM库一起使用.CoCreateInstance()将调用此函数(如果尚未调用),然后将您在库中实现的类的实例添加到堆上,最后返回指向该对象的原始指针.当然,它可能在此过程中失败,因此您可以使用某种机制来检查状态,如HRESULT.
为了简单使用它,您可以将COM库视为一个常见的DLL,1)一些预定义的入口(主)函数,2)您必须调用一些预定义的函数,如CoCreateInstance()来输入它,并接受它就像因为它必须.