Home > Back-end >  Associate clsid with Runtime Class for winrt::create_instance Function to Late Bind Runtime Class in
Associate clsid with Runtime Class for winrt::create_instance Function to Late Bind Runtime Class in

Time:07-16

How can a Guid be associated with a Runtime Class to be used in the function call winrt::create_instance, so a winrt Runtime Class can be late bound? I don't see how in MIDL 3.0, though Interfaces work with uuid and version. Is this the answer to late binding in WinRT?

CodePudding user response:

I still don't know how to use winrt::create_instance, but I took a really deep look into base.h. I found plenty of guts to late bind to a WinRT component dll using def calls and interop. This is my solution to the problem. It works. Choosing the right way to hold IUnknown was important, and there was some specifics I'm still working out; like why I have to wrap the IUnknown in a winrt::impl::abi_t<> (WinRT/COM conversion?). Using the following code you simply load the dll by file name (with qualified path if not in in the executable directory), and call the class according to it's runtime namespace.classname. It is absolutely not necessary to add the activatableclass to the Packackage.appxmanifest or to reference the winmd. A search shows a lot of people looking for this, but there is a general reluctance to point this out. It's just like COM really, with its own quirks.

UINT32 ret = 0;

void* dllHandle = WINRT_IMPL_LoadLibraryW(L"Project.dll");

if (!dllHandle) { throw; };

void* pProc = WINRT_IMPL_GetProcAddress(dllHandle, "DllGetActivationFactory");
auto DllGetActivationFactory = reinterpret_cast<int32_t(__stdcall*)(void* classId, void** factory)>(pProc);

static const WCHAR* cname = L"namespace.classname";
const UINT32 cnamelen = wcslen(cname);

HSTRING hcname = NULL;
HSTRING_HEADER header;
HRESULT hr = WindowsCreateStringReference(cname, cnamelen, &header, &hcname);

com_ptr< winrt::impl::abi_t<winrt::Windows::Foundation::IActivationFactory> > oCOMActivationFactory{ nullptr };
ret = (*DllGetActivationFactory)(&header, oCOMActivationFactory.put_void());

com_ptr< winrt::impl::abi_t<winrt::Windows::Foundation::IUnknown> > iObj{ nullptr };
ret = oCOMActivationFactory.get()->ActivateInstance(iObj.put_void());

ProxyServer::ImplementationInterface iImplementationInterface{ nullptr };
iImplementationInterface = iObj.as<ProxyServer::ImplementationInterface>();

iImplementationInterface.MyFunction();
       
oCOMActivationFactory.detach();

WindowsDeleteString(hcname);
  • Related