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

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

问题描述

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



所以,我有一个DLL,我正在开发,我需要一些功能,单独的COM DLL。当我看到COM DLL与Depends.exe我看到的方法像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();



EDIT:




Windows知道关于COM DLL实现的类型[...和]
它们是什么DLL实现在


...我真的很了解Windows如何知道这一点。这不是魔术,虽然它可能看起来有点隐匿起初。



COM库提供类型库,其中列出了库提供的接口和CoClasses。这种类型库是硬盘驱动器上的文件的形式 - 通常它直接嵌入在同一个DLL或EXE作为库本身。 Windows通过查找Windows注册表知道在哪里找到类型库和COM库本身。



当您调用 CoCreateInstance 时,Windows会自动启动在Windows注册表中查找clsid,找到相应的DLL,加载它,并在实现COM对象的DLL中执行正确的代码。



进入Windows注册表?当安装COM DLL时,它被注册。这通常通过运行 regsvr32.exe 来完成,然后将您的DLL加载到内存中,并调用名为<$的函数c $ c> 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天全站免登陆