FANDOM


It may be desirable to call an in-proc COM object directly, without using the system CoCreateInstance that goes through the registry. Therefore, the technique here works even if the COM object isn't registered. However, this only works with COM objects inside of DLLs, and since the COM object isn't registered, and the OS knows nothing about your COM object, it can't marshal data across apartments. Care must be taken when using this technique.

COMComponentDLL.hEdit

#pragma once

#include <sstream>

// This class allows you to CoCreate an instance without going through the OS.
// Thus, the component doesn't have to be registered.
// Code is for unit testing only at the moment.  To use in production code, it needs more diagnostics.
// Example:
//	// First Load the DLL
//	COMComponentDLL fooDLL(L"C:\\Program Files\\......\\FOO.dll");
//	
//	// Create the Foo object and get a reference to an IFoo interface.
//	CComPtr<IFoo> foo;
//	fooDLL.CoCreateInstance(__uuidof(CoFoo), &foo );
class COMComponentDLL
{
private:
	HINSTANCE				 m_hInst;
	HRESULT (STDAPICALLTYPE* m_fpDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID * ppv);

	void SetupDLL(LPCWSTR componentFullPath)
	{
		m_hInst = ::LoadLibrary(componentFullPath);
		if ( m_hInst == NULL )
			throw; // don't do this in production code.

		*(void **)&m_fpDllGetClassObject = GetProcAddress(m_hInst, "DllGetClassObject");	
		if ( m_fpDllGetClassObject == NULL )
			throw; // don't do this in production code.
	}

public:
	// Creates an object given a full path to a COM module.
	//
	// Load DLL by specifying the full path.
	// Example:
	//	COMComponentDLL fooDLL(L"C:\\Program Files\\......\\FOO.dll");
	//
	// When using from a Visual Studio Test project, the TestContext Property can be used to determine the location of the component.
	// Example:
	//   #include <msclr\marshal_cppstd.h>
	//   ...
	//
	//   std::wstring componentFullPath = msclr::interop::marshal_as<std::wstring>( TestContext->TestDir );
	//   componentFullPath += L"\\..\\..\\..\\Release\\FOO.dll";
	//   COMComponentDLL broDLL(componentFullPath.c_str());
	COMComponentDLL(LPCWSTR componentFullPath)
	{
		SetupDLL( componentFullPath ); 
	}

	~COMComponentDLL()
	{
		::FreeLibrary( m_hInst );
	}

	template <class T>
	void CoCreateInstance(const CLSID& coClass, T** ppObj )
	{
		// First get the class factory
		CComPtr<IClassFactory> classFactory;
		if ( FAILED( m_fpDllGetClassObject(coClass, IID_IClassFactory, (LPVOID*)&classFactory) ))
			throw; // don't do this in production code.

		// Then create the instance.
		if ( FAILED( classFactory->CreateInstance(NULL, __uuidof(T), (LPVOID*)ppObj) ))
			throw; // don't do this in production code.
	}
};

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.