I want to create a WinRT component using C++ and WRL (Windows Runtime C++ Template Library) to be consumable in a managed code via C# static method call.
int sum = Math.FastAdd(5,6);
The implementation which doesn't work for me is below.
What can be wrong here?
- In the IDL file create a Math class. It will be a host for static methods on a managed side. Create IMathStatics interface with FastAdd method. This one just contains a bunch of static methods. Mark Math class with a static attribute with the parameter of IMathStatics.
import "inspectable.idl";
#define COMPONENT_VERSION 1.0
namespace WRLNativeComponent
{
runtimeclass Math;
[uuid(EFA9D613-BA8F-4F61-B9E7-C6BE7B7765DD)]
[exclusiveto(WRLNativeComponent.Math)]
[version(COMPONENT_VERSION)]
interface IMathStatics : IInspectable
{
HRESULT FastAdd([in] int a, [in] int b, [out, retval] int* value);
}
[uuid(650438BA-C401-49E1-8F06-58DCD5A4B685), version(COMPONENT_VERSION)]
interface IMath : IInspectable
{
HRESULT InstanceMethod(void);
}
[static(WRLNativeComponent.IMathStatics, COMPONENT_VERSION)]
[version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
runtimeclass Math
{
[default] interface IMath;
}
}
- Create MathStatics C++ class. Let InspectableClassStatic macro to point to IMathStatics string identifier. Add ActivatableStaticOnlyFactory macro to point to MathStatics class implementation.
#pragma once
#include <wrl.h>
#include "MyMath_h.h" // generated from IDL
using namespace Microsoft::WRL;
namespace WRLNativeComponent {
class Math : public Microsoft::WRL::RuntimeClass,
ABI::WRLNativeComponent::IMath>
{
InspectableClass(RuntimeClass_WRLNativeComponent_Math, BaseTrust);
public:
Math(void) {}
~Math(void) {}
STDMETHODIMP InstanceMethod() override
{
return S_OK;
}
};
class MathStatics : public Microsoft::WRL::ActivationFactory
{
InspectableClassStatic(InterfaceName_WRLNativeComponent_IMathStatics, BaseTrust);
public:
MathStatics(void) {}
~MathStatics(void) {}
STDMETHODIMP FastAdd(_In_ int a, _In_ int b, _Out_ int* value) override
{
if (value == nullptr) return E_POINTER;
*value = a + b;
return S_OK;
}
};
ActivatableClass(Math);
ActivatableStaticOnlyFactory(MathStatics);
}
After compilation the WRLNativeComponent.winmd file is created. I can see the Math class with public static FastAdd method.
Construct C# client to call the static method. When the call is made, the 'System.InvalidCastException' is thrown. This expected to work correctly.