我有一个纯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:
假设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项目
发布评论