c++windows-runtimeprojectionc++-winrtwinrt-component

How to convert from float3 to C++/WinRT type?


I'm writing a custom C++/WinRT component which will be consumed from a C# application. Inside this component I have objects that I need to expose to the caller application and these objects have properties, in this case an Id and a Position. The Id is an integer type, and the Position is float3.

Here are the contents of the .idl and the header file: .idl:

 runtimeclass MyObject
    {
        MyObject();
        Int32 Id();
        Windows::Foundation::Numerics::float3 Position();
    }

.h:

#pragma once
#include "MyObject.g.h"

namespace winrt::TestComponent::implementation 
{
    struct MyObject : MyObjectT<MyObject>
    {
        MyObject();
        int32_t Id();
        Windows::Foundation::Numerics::float3 Position();

    private:
        int _id;
        Windows::Foundation::Numerics::float3 _position;
    };
}

namespace winrt::TestComponent::factory_implementation
{ 
    struct MyObject : MyObjectrT<MyObject, implementation::MyObject>
    {
    };
}

It looks like that Windows::Foundation::Numerics::float3 is not supported inside .idl files, when I try to build the project the process fails with [msg]syntax error [context]: expecting an identifier near ":" error at the line where the Position() is declared inside the .idl. What would be the best way to use expose float3 property of a runtime class using C++/WinRT?


Solution

  • float3 is the standard WinRT projected type for C++. What you want to use in the idl (which is supposed to be language agnostic) is the Windows.Foundation.Numerics.Vector3 WinRT type and float3 in all .h or .cpp files, something like this:

    class.idl:

    namespace RuntimeComponent1
    {
        [default_interface]
        runtimeclass Class
        {
            Class();
            Int32 MyProperty;
            Windows.Foundation.Numerics.Vector3 Position();
        }
    }
    

    class.h:

    #pragma once
    
    #include "Class.g.h"
    
    namespace winrt::RuntimeComponent1::implementation
    {
        struct Class : ClassT<Class>
        {
            Class() = default;
    
            int32_t MyProperty();
            void MyProperty(int32_t value);
            Windows::Foundation::Numerics::float3 Position();
        };
    }
    
    namespace winrt::RuntimeComponent1::factory_implementation
    {
        struct Class : ClassT<Class, implementation::Class>
        {
        };
    }
    

    class.cpp:

    #include "pch.h"
    #include "Class.h"
    #include "Class.g.cpp"
    
    namespace winrt::RuntimeComponent1::implementation
    {
        int32_t Class::MyProperty()
        {
            throw hresult_not_implemented();
        }
    
        void Class::MyProperty(int32_t /* value */)
        {
            throw hresult_not_implemented();
        }
    
        Windows::Foundation::Numerics::float3 Class::Position()
        {
            throw hresult_not_implemented();
        }
    }