![]() |
Platforms, Frameworks & Libraries »
COM / COM+ »
COM
Intermediate
Emulating CoCreateInstance()By lallousDescribes how to use COM objects without registration. |
VC6, VC7, VC7.1, VC8.0Win2K, WinXP, Win2003, Visual Studio, COM, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
A while ago, I wrote a small utility that converts DOT syntax into an image using the WinGraphViz.DLL COM component.
However, it is not very usual to have the user register this component before running the tool, thus I started looking around for a way to use COM components as if they were normal DLLs. The research yielded that there are many techniques to accomplish that:
CoCreateInstance() To learn more about Registration-Free COM, please check the references at the end of this article.
Normally, to create an instance, you would do something like:
hr = CoCreateInstance(CLSID_DOT, NULL, CLSCTX_ALL,
IID_IDOT, (LPVOID *)&pIDOT);
This will cause OLE to fetch the associated DLL from the registry and call its DllGetClassObject() method to get a class factory, then from the class factory an instance of your required IID will be created.
For that reason, we may emulate the CoCreateInstance() by the following code:
HRESULT __stdcall MyCoCreateInstance( LPCTSTR szDllName, IN REFCLSID rclsid, IUnknown* pUnkOuter, IN REFIID riid, OUT LPVOID FAR* ppv) { HRESULT hr = REGDB_E_KEYMISSING; HMODULE hDll = ::LoadLibrary(szDllName); if (hDll == 0) return hr; typedef HRESULT (__stdcall *pDllGetClassObject)(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR* ppv); pDllGetClassObject GetClassObject = (pDllGetClassObject)::GetProcAddress(hDll, "DllGetClassObject"); if (GetClassObject == 0) { ::FreeLibrary(hDll); return hr; } IClassFactory *pIFactory; hr = GetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&pIFactory); if (!SUCCEEDED(hr)) return hr; hr = pIFactory->CreateInstance(pUnkOuter, riid, ppv); pIFactory->Release(); return hr; }
Notice how this function takes a parameter holding the DLL's name.
You need your application to run first if the COM is registered, if not you would resort to emulating the CoCreateInstance(). Your code could look like this:
hr = CoCreateInstance(CLSID_DOT, NULL, CLSCTX_ALL,
IID_IDOT, (LPVOID *)&pIDOT);
if (hr == REGDB_E_CLASSNOTREG)
{
hr = MyCoCreateInstance(_T("WinGraphViz.dll"), CLSID_DOT,
NULL, IID_IDOT, (LPVOID *)&pIDOT);
}
if (FAILED(hr))
{
cout << "CoCreateInstance Failed: " << hr
<< "nn";
return -1;
}
The following links were helpful during the building of this simple snippet:
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 16 Apr 2007 Editor: Smitha Vijayan |
Copyright 2007 by lallous Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |