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.