我得到了以下C++/CX代码,它按预期工作,但希望将其转换为C++/WinRT代码:
namespace My.Custom.Stuff
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class BaseClass : public Windows::UI::Xaml::Controls::SwapChainPanel
{
public:
BaseClass();
void PublicMethod();
protected:
static ::DirectX::XMFLOAT3 ProtectedMethod();
};
}
namespace My.Custom.Stuff
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class SubClass sealed : public BaseClass
{
public:
SubClass();
void UseProtectedMethod()
{
::DirectX::XMFLOAT3 value = ProtectedMethod()
// ...
}
};
}
然而,我遇到的问题如下:BaseClass
包含一个受保护的方法,该方法返回的类型无法映射到相应的Windows运行时类型。在C++/CX中,这不是问题,因为ProtectedMethod
根本没有映射。如果我使用我的Windows运行时组件ProtectedMethod
,那就是我想要的。
但是,该方法应该是BaseClass
的成员,因为像SubClass
这样的多个其他类在实现其公共方法时使用该方法。我已经想出了以下C++/WinRT MIDL代码:
namespace My.Custom.Stuff
{
unsealed runtimeclass BaseClass : Windows.UI.Xaml.Controls.SwapChainPanel
{
BaseClass();
void PublicMethod();
// This does not work
protected DirectX.XMFLOAT3 RgbFromBrush(IInspectable brush);
}
}
import "BaseClass.idl";
namespace My.Custom.Stuff
{
runtimeclass SubClass : BaseClass
{
SubClass();
void UseProtectedMethod();
}
}
问题是,如果我以这种方式定义ProtectedMethod
,它将不起作用,因为::DirectX::XMFLOAT3
不是Windows运行时类型。如果我使用任何其他返回类型,受保护的方法就会被映射。但是,当使用Windows运行时组件时,它不应该是可见的,当然我不应该更改它的返回类型。
如何使用C++/WinRT实现我对C++/CX的操作?
编辑
编译MIDL代码的结果如下:
#include "BaseClass.g.h"
namespace winrt::My::Custom::Stuff::implementation
{
struct BaseClass : BaseClassT<BaseClass>
{
BaseClass() = default;
// ...
};
}
namespace winrt::My::Custom::Stuff::factory_implementation
{
struct BaseClass : BaseClassT<BaseClass, implementation::BaseClass>
{
};
}
我认为可以简单地添加受保护的方法如下:
namespace winrt::My::Custom::Stuff::implementation
{
struct BaseClass : BaseClassT<BaseClass>
{
BaseClass() = default;
protected:
static ::DirectX::XMFLOAT3 ProtectedMethod();
};
}
但是,尝试在SubClass
中使用ProtectedMethod
会导致以下错误:
error C2039: 'ProtectedMethod': is not a member of 'winrt::My::Custom::Stuff::BaseClass'
以下是我如何使用它:
#include "SubClass.g.h"
namespace winrt::My::Custom::Stuff::implementation
{
struct SubClass : SubClassT<SubClass>
{
SubClass() = default;
void UseProtectedMethod()
{
::DirectX::XMFLOAT3 value = ProtectedMethod();
}
};
}
namespace winrt::My::Custom::Stuff::factory_implementation
{
struct SubClass : SubClassT<SubClass, implementation::SubClass>
{
};
}
从C++/CX转换到C++/WinRT时,只有公共方法才能进入IDL文件,因为这些方法是构成WinRT API曲面的唯一方法。
私有/受保护/内部的方法不是WinRT API表面的一部分,因此它们不应进入IDL。
您发布的使用代码不应该编译,因为implementation::SubClass
的C++定义缺少一个模板参数。由于IDL/WinRT定义具有从BaseClass
派生的SubClass
,因此需要将BaseClass
的实现类型提供给SubClassT
,并且如果检查cppwirt生成的";h"子类;,你会看到这种情况发生的。一旦您正确地声明了SubClass
的实现,您就可以访问BaseClass
上受保护的方法。
我刚刚成功地尝试了一下,它看起来像这样:
BaseClass.idl
namespace RuntimeComponent1
{
[default_interface]
unsealed runtimeclass BaseClass
{
BaseClass();
void PublicMethod();
}
}
基本类.h
#pragma once
#include "BaseClass.g.h"
struct non_winrt_type
{
};
namespace winrt::RuntimeComponent1::implementation
{
struct BaseClass : BaseClassT<BaseClass>
{
BaseClass() = default;
void PublicMethod() {}
protected:
non_winrt_type ProtectedMethod()
{
return {};
}
};
}
namespace winrt::RuntimeComponent1::factory_implementation
{
struct BaseClass : BaseClassT<BaseClass, implementation::BaseClass>
{
};
}
子类.idl
import "BaseClass.idl";
namespace RuntimeComponent1
{
[default_interface]
runtimeclass SubClass : BaseClass
{
SubClass();
void UseProtectedMethod();
}
}
子类.h
#pragma once
#include "SubClass.g.h"
#include "BaseClass.h"
namespace winrt::RuntimeComponent1::implementation
{
// Notice how BaseClass is used here.
// This was copied directly from the generated boilerplate SubClass.h
struct SubClass : SubClassT<SubClass, RuntimeComponent1::implementation::BaseClass>
{
SubClass() = default;
void UseProtectedMethod()
{
auto result = ProtectedMethod();
}
};
}
namespace winrt::RuntimeComponent1::factory_implementation
{
struct SubClass : SubClassT<SubClass, implementation::SubClass>
{
};
}