Skip to content

Instantly share code, notes, and snippets.

@forderud
Created July 7, 2019 20:47
Show Gist options
  • Save forderud/f9e3705002ae106f676f14481a5285fd to your computer and use it in GitHub Desktop.
Save forderud/f9e3705002ae106f676f14481a5285fd to your computer and use it in GitHub Desktop.
#pragma once
#include <Windows.h>
#include <atlbase.h>
/** Programmatically creates an instance of a a COM object found in a specific DLL.
Confirmed to work with UWP if the DLL is placed in the same "AppX" folder as the UWP app.
WARNING: Will _leak_ handle to the DLL to avoid premature DLL unloading. The good
way to handle this would be to also return a RAII wrapper of the DLL handle, and
let the caller be responsible for freeing it after the object have been deleted. */
static CComPtr<IUnknown> CreateComObject (const std::wstring& fileName, const CLSID& classId) {
// load DLL (handle is leaked)
HMODULE dll_handle = LoadPackagedLibrary(fileName.c_str(), NULL);
if (!dll_handle)
return CComPtr<IUnknown>();
// get class object
typedef HRESULT(STDAPICALLTYPE *DllGetClassObject_t)(const CLSID& clsid, const IID& iid, void** ppv);
DllGetClassObject_t dllGetClassObject = reinterpret_cast<DllGetClassObject_t>(GetProcAddress(dll_handle, "DllGetClassObject"));
if (!dllGetClassObject)
return CComPtr<IUnknown>();
// get factory function
CComPtr<IClassFactory> iClassFactory;
HRESULT res = dllGetClassObject(classId, IID_IClassFactory, reinterpret_cast<void**>(&iClassFactory));
if (FAILED(res))
return CComPtr<IUnknown>();
// create loader object
CComPtr<IUnknown> instance;
res = iClassFactory->CreateInstance(nullptr, IID_IUnknown, reinterpret_cast<void**>(&instance));
if (FAILED(res))
return CComPtr<IUnknown>();
return instance;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment