将c ++(DLL)项目转换为COM DLL项目

编程入门 行业动态 更新时间:2024-10-21 13:01:39
本文介绍了将c ++(DLL)项目转换为COM DLL项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个纯C ++项目(DLL),我想转换为COM项目,例如。在标题中定义的所有公共接口,现在将显示为COM接口(IDL等...)。最终产品应该是COM Dll。

Hi I have a pure C++ project (DLL) which I would like to convert to COM project, e.g. all public interfaces defined in headers, will now be exposed as COM interfaces (IDL etc...). And the final product should be COM Dll.

如何开始?如何定义任何高级准则?好的文章?

How do I start? How do I define Any high level guidelines? good articles?

推荐答案

这个问题至少有两个部分:

There are at least two parts to this problem:

首先,COM对象是使用 CoCreateInstance 。 CoCreateInstance在内存中查找COM注册(通过 CoRegisterClassObject ),在应用程序清单中作为零reg COM对象,最后在注册表中。

First, COM objects are created using CoCreateInstance. CoCreateInstance looks for COM registrations in memory (via CoRegisterClassObject), in the applications manifest as a zero reg COM object, and finally, in the registry.

对于零reg,创建一个程序集清单描述您的dll以便对象的使用者可以向他们的

For zero reg, create an assembly manifest describing your dll so that consumers of your object can add a dependantAssembly reference to their application manifest.

然后,COM dll需要至少两个入口点: DllGetClassObject 和 DllCanUnloadNow

Then, a COM dll needs at least two entry points: DllGetClassObject and DllCanUnloadNow

您通过创建一个工厂对象的实例来实现 DllGetClassObject - 它支持 IClassFactory - 可用于

You implement DllGetClassObject by creating an instance of a factory object - that supports IClassFactory - that can be used to make instances of your actual object.

因此,总结一种TDD驱动的实现COM dll的方法:

So, to summarize - a kind of TDD driven approach to implementing a COM dll:

  • 创建一个带有'DllGetClassObject'和'DllCanUnloadNow'入口点的DLL。
  • 创建一个新的GUID来表示你的对象,
  • 创建一个测试应用程序,该应用程序使用该GUID调用 CoCreateInstance 。
  • 调用CoCreateInstance现在应该在您的DllGetClassObject调用中。实现类工厂对象。
  • 实施 CreateInstance 方法创建一个新的c ++类的实例。确保所有接口派生自(至少)IUnknown。在您自己新创建的对象上调用QueryInterface以获取并返回所需的界面。
  • Create a DLL with 'DllGetClassObject' and 'DllCanUnloadNow' entry points.
  • Create a new GUID to represent your object, and create a assembly manifest describing the COM object your dll (will) contain.
  • Create a test application, that calls CoCreateInstance with that GUID.
  • Calling CoCreateInstance should now land up in your DllGetClassObject call. Implement the class factory object.
  • Implement the CreateInstance method to create a new instance of your c++ class. Ensure that all your interfaces derive from (at least) IUnknown. Call QueryInterface on your own newly created object to get and return the desired interface.
  • 假设Visual Studio(Express is ok)是您的构建环境:

    Assuming Visual Studio (Express is ok) is your build environment:

    创建测试exe:

    // main.cpp #include <windows.h> #include <objbase.h> #include <initguid.h> DEFINE_GUID(CLSID_RegFreeOcx,0x00000000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); #if defined _MSC_VER #if !defined _WINDLL && !defined (_CONSOLE) #pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") #endif #endif #pragma comment(linker, "/manifestDependency:\"name='acme.RegFreeOcx' processorArchitecture='*' version='1.0.0.0' type='win32' \"") int main(){ CoInitialize(NULL); IUnknown* pUnk; CoCreateInstance(CLSID_RegFreeOcx,NULL,CLSCTX_ALL,IID_IUnknown,(void**)&pUnk); if(pUnk) pUnk->Release(); }

    创建用于reg免费激活COM dll的清单:

    Create the manifest for reg free activation of the COM dll:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity name="Acme.RegFreeOcx" processorArchitecture="x86" version="1.0.0.0" type="win32" /> <file name = "RegFreeOcx.dll"> <comClass clsid="{00000000-0000-0000-0000-000000000000}" threadingModel="Apartment" /> </file> </assembly>

    创建dll项目

    // dllmain.cpp #include <windows.h> #pragma comment(linker,"/export:DllGetClassObject=_DllGetClassObject@12,PRIVATE") #pragma comment(linker,"/export:DllCanUnloadNow=_DllCanUnloadNow@0,PRIVATE") #include <objbase.h> #include <initguid.h> DEFINE_GUID(CLSID_RegFreeOcx,0x00000000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); #include "MyClassFactory.hpp" STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid,void** ppvObj) { if(CLSID_RegFreeOcx == clsid){ MyClassFactory* pFactory = new MyClassFactory(); HRESULT result = pFactory->QueryInterface(riid,ppvObj); pFactory->Release(); return result; } return E_FAIL; } STDAPI DllCanUnloadNow() { return E_FAIL; } //MyClassFactory.hpp #include <MyClass.hpp> class MyClassFactory : public IClassFactory { volatile ULONG _cRef; public: MyClassFactory():_cRef(1){} virtual ~MyClassFactory(){} public: // IUnknown STDMETHODIMP_(ULONG)AddRef(){ return InterlockedIncrement(&_cRef); } STDMETHODIMP_(ULONG)Release(){ ULONG result = InterlockedDecrement(&_cRef); if(!result) delete this; return result; } STDMETHODIMP QueryInterface(REFIID riid, void** ppvObj){ if(riid == IID_IUnknown || riid == IID_IClassFactory) *ppvObj = (IClassFactory*)this; else { *ppvObj=0; return E_NOINTERFACE; } AddRef(); return S_OK; } public: // IClassFactory STDMETHODIMP CreateInstance(IUnknown* pUnkOuter,REFIID riid,void** ppvObj){ if(pUnkOuter) return E_INVALIDARG; MyClass* pClass = new MyClass(); HRESULT result = pClass->QueryInterface(riid,ppvObj); pClass->Release(); return result; } STDMETHODIMP LockServer(BOOL fLock){ return E_NOTIMPL; } };

    最后,定义自己的类。你可以使用IDL来做到这一点,但对于其他cpp消费者,你只需在头文件中定义它。

    And finally, define your own class. You could use IDL to do this but, for other cpp consumers, you can just define it in a header file.

    // IMyClass.h #include <objbase.h> DEFINE_GUID(IID_MyInterface,0x00000000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); interface IMyInterface : IUnknown { STDMETHOD(MyMethod)(void)PURE; };

    实现在cpp文件中实现IMyInterface的类,与ClassFactory的实现方式根据IUnknown方法) - 用您自己的接口交换对IClassFactory的引用。

    Implement the class that implements IMyInterface in a cpp file in much the same way that the ClassFactory was implemented (in terms of the IUnknown methods) - swapping out references to IClassFactory with your own interface.

    更多推荐

    将c ++(DLL)项目转换为COM DLL项目

    本文发布于:2023-11-17 07:16:25,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1609274.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:项目   转换为   DLL

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!