uwp - 如何将返回非 Windows 运行时类型的受保护方法添加到 C++/WinRT 基类
问题描述
我得到了以下 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();
};
}
但是,尝试使用ProtectedMethod
inSubClass
会导致以下错误:
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。
您发布的使用代码不应编译,因为您的 C++ 定义implementation::SubClass
缺少模板参数。由于 IDL/WinRT 定义SubClass
派生自BaseClass
,因此您需要将BaseClass
的实现类型提供给SubClassT
,如果您检查 cppwinrt 生成的“SubClass.h”的内容,您会看到这种情况发生。一旦你SubClass
正确地声明了你的实现,你就可以访问受保护的方法了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>
{
};
}
推荐阅读
- react-native - 使用 react-native-share 共享图像、链接和标题不起作用
- express - 为什么我不能在 nuxt 的 serverMiddleware 中创建带有参数的路由?
- flutter - fromJson 抛出 Expected 'Map 类型的值
',但得到了“_JsonDocumentSnapshot”类型之一 - rabbitmq - 在windows上运行rabbitmq
- php - 在 PHP IF 语句中使用 Yoda 条件时遇到问题
- javascript - Electron 应用程序中渲染器脚本中的窗口对象不包含来自预加载脚本的数据
- android - Android将页脚添加到抽屉布局
- c++ - 如何从另一个 DirectShow 过滤器或捕获设备填充缓冲区我的虚拟网络摄像头
- f# - 如何查看 FSI 中的调用堆栈?
- python - Nginx Permission Denied 但有权限(nginx、gunicorn、django)