如何在C ++中使用LoadLibrary的COM DLL [英] How do I use a COM DLL with LoadLibrary in C++

查看:260
本文介绍了如何在C ++中使用LoadLibrary的COM DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,COM对我来说就像是黑魔法。但是我需要在一个我正在开发的项目中使用COM dll。



所以,我有一个我正在开发的DLL,我需要一些可用的功能单独的COM DLL。当我使用Depends.exe查找COM DLL时,我会看到类似DllGetClassObject()和其他函数的方法,但没有一个我感兴趣的函数。



我有访问权限到COM DLL(旧版)源代码,但它是一个混乱,我宁愿使用COM DLL的二进制,像一个大黑盒子,不知道里面发生了什么。



那么,如何使用LoadLibrary从我的代码中调用COM DLL函数?可能吗?如果是的,是否可以给我一个如何做的例子?



我在这个项目中使用Visual Studio 6。



非常感谢!

解决方案

通常你会使用 CoCreateInstance() / code>从COM DLL中实例化一个对象。当您这样做时,不需要首先加载DLL,并获得proc地址,就像您需要使用正常的DLL一样。这是因为Windows知道COM DLL实现的类型,它们实现的DLL以及如何实例化它们。 (假设当然注册了COM DLL,它通常是注册的)。



假设你有一个COM DLL,要使用IDog接口。在这种情况下,



dog.idl



 接口IDog:IUnknown 
{
HRESULT Bark();
};

coclass Dog
{
[默认值]接口IDog;
};



myCode.cpp



  IDog * piDog = 0; 
CoCreateInstance(CLSID_DOG,0,CLSCTX_INPROC_SERVER,IID_IDOG,& piDog); // windows将实例化IDog对象,并将指针放在piDog
piDog-> Bark()中; // do stuff
piDog-> Release(); //现在完成了
piDog = 0; //不需要删除它 - COM对象通常删除自己

所有这些内存管理的东西都可以得到尽管如此,ATL还提供了智能指针,使得实例化和管理这些对象有点简单:

  CComPtr< IDog>狗; 
dog.CoCreateInstance(CLSID_DOG);
dog-> Bark();



编辑:



那个:


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 / DllRegisterServer 进程,然后 CoCreateInstance 将失败,并显示一条错误:


类不注册


幸运的是,这个修复是简单地调用你的 regsvr32 COM服务器,然后重试。


First, COM is like black magic for me. But I need to use COM dll in one project I'm working on.

So, I have a DLL I am developing and I need some functionalities that are available in a separate COM DLL. When I look to the COM DLL with Depends.exe I see methods like DllGetClassObject() and other functions but none of the functions I'm interested in.

I have access to the COM DLL (legacy) source code but it's a mess and I'd rather like to use the COM DLL in binary like a big black box not knowing what's going on inside.

So, how can I call the COM DLL functions from my code using LoadLibrary? Is it possible? If, yes, could you give me an example of how to do it?

I'm using Visual Studio 6 for this project.

Thanks a lot!

解决方案

Typically you would use CoCreateInstance() to instantiate an object from a COM DLL. When you do this, there's no need to load the DLL first and get proc addresses like you would need to do with a normal DLL. This is because Windows "knows" about the types that a COM DLL implements, what DLL they are implemented in, and how to instantiate them. (Assuming of course that the COM DLL is registered, which it typically is).

Suppose you have a COM DLL with the IDog interface you want to use. In that case,

dog.idl

interface IDog : IUnknown
{
  HRESULT Bark();
};

coclass Dog
{
  [default] Interface IDog;
};

myCode.cpp

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

All this memory management stuff can get pretty grungy, though, and the ATL provides smart pointers that make the task of instantiating & managing these objects a little easier:

CComPtr<IDog> dog;
dog.CoCreateInstance(CLSID_DOG);
dog->Bark();

EDIT:

When I said above that:

Windows "knows" about the types that a COM DLL implements [...and] what DLL they are implemented in

...I really glossed over exactly how Windows knows this. It's not magic, although it might seem a little occult-ish at first.

COM libraries come with Type Libraries, which list the Interfaces and CoClasses that the library provides. This Type Library is in the form of a file on your hard drive -- very often it is embedded directly in the same DLL or EXE as the library itself. Windows knows where to find the Type Library and the COM Library itself by looking in the Windows Registry. Entries in the Registry tell Windows where on the hard drive the DLL is located.

When you call CoCreateInstance, Windows looks the clsid up in the Windows Registry, finds the corresponding DLL, loads it, and executes the proper code in the DLL that implements the COM object.

How does this information get in to the Windows Registry? When a COM DLL is installed, it is registered. This is typically done by running regsvr32.exe, which in turn loads your DLL in to memory and calls a function named DllRegisterServer. That function, implemented in your COM server, adds the necesarry information to the Registry. If you are using ATL or another COM framework, this is probably being done under the hood so that you don't have to interface with the Registry directly. DllRegisterServer only needs to be called once, at install-time.

If you try to call CoCreateInstance for a COM object that has not yet been registered via the regsvr32/DllRegisterServer process, then CoCreateInstance will fail with an error that says:

Class Not Registered

Fortunately, the fix for this is to simply call regsvr32 on your COM server, and then try again.

这篇关于如何在C ++中使用LoadLibrary的COM DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆