WRL을 사용하여 기본 제공 winrt 구성 요소를 반환하는 방법은 무엇입니까?
-
12-12-2019 - |
문제
WRL을 사용하여 winrt 구성 요소를 만들 때 문제는 WRL만 사용할 수 있다는 것입니다. ABI::Windows::xxx
네임스페이스를 사용할 수 없습니다. Windows::UI::Xaml::Media::Imaging
WRL의 네임스페이스입니다.
그런 다음 기본 제공 winrt 구성 요소를 반환 값으로 만드는 방법은 무엇입니까?
// idl
import "inspectable.idl";
import "Windows.Foundation.idl";
import "Windows.UI.Xaml.Media.Imaging.idl";
namespace Decoder
{
interface IPhotoDecoder;
runtimeclass PhotoDecoder;
interface IPhotoDecoder : IInspectable
{
HRESULT Decode([in] int width, [in] int height, [out, retval] Windows.UI.Xaml.Media.Imaging.BitmapImage **ppBitmapImage);
}
[version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
runtimeclass PhotoDecoder
{
[default] interface IPhotoDecoder;
}
}
// cpp
using namespace Microsoft::WRL;
using namespace Windows::Foundation;
using namespace ABI::Windows::UI::Xaml::Media::Imaging;
namespace ABI
{
namespace Decoder
{
class PhotoDecoder: public RuntimeClass<IPhotoDecoder>
{
InspectableClass(L"Decoder.PhotoDecoder", BaseTrust)
public:
PhotoDecoder()
{
}
HRESULT __stdcall Decode(_In_ int width, _In_ int height, _Out_ IBitmapImage **ppBitmapImage)
{
// How to create Windows.UI.Xaml.Media.Imaging.BitmapImage without using Windows::UI::Xaml::Media::Imaging
}
};
ActivatableClass(PhotoDecoder);
}
}
해결책
네임스페이스에는 두 가지 세트가 있습니다.
- 전역 네임스페이스에 뿌리를 둔 것(예:
Windows::Foundation
) - 에 뿌리를 둔 사람들
ABI
네임스페이스(예:ABI::Windows::Foundation
)
각각의 내용은 "동일하다". 예를 들어, Windows::Foundation::IUriRuntimeClass
동일한 인터페이스의 이름을 지정합니다. ABI::Windows::Foundation::IUriRuntimeClass
.
그렇다면 네임스페이스 세트가 두 개인 이유는 무엇입니까?전역 네임스페이스에 루트가 있는 네임스페이스는 C++/CX에서 사용하도록 예약되어 있습니다.해당 네임스페이스에 런타임 클래스의 프로젝션을 생성합니다.WRL을 사용하는 경우 항상 다음 위치에 있는 네임스페이스로 작업하게 됩니다. ABI
네임스페이스("비투영" 이름, 즉 정확히 ABI 레이어에 존재하는 이름)
런타임 클래스는 두 가지 방법 중 하나로 인스턴스화("활성화")됩니다.유형이 기본 생성 가능한 경우 호출을 통해 기본 생성될 수 있습니다. RoActivateInstance
.유형이 다른 생성자를 선언하는 경우 다음을 호출하여 런타임 유형에 대한 활성화 팩토리를 가져와 해당 생성자를 호출할 수 있습니다. RoGetActivationFactory
.예를 들어, 기본적으로 BitmapImage
이렇게:
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::UI::Xaml::Media::Imaging;
HStringReference classId(RuntimeClass_Windows_UI_Xaml_Media_Imaging_BitmapImage);
ComPtr<IInspectable> inspectable;
if (FAILED(RoActivateInstance(classId.Get(), inspectable.GetAddressOf())))
{
// Handle failure
}
ComPtr<IBitmapImage> bitmapImage;
if (FAILED(inspectable.As(&bitmapImage)))
{
// Handle failure
}
WRL에는 유용한 기능 템플릿도 있습니다. Windows::Foundation::ActivateInstance
, 둘 다 호출 RoActivateInstance
그리고 QueryInterface
원하는 대상 인터페이스로:
using namespace Windows::Foundation;
ComPtr<IBitmapImage> bitmapImage;
if (FAILED(ActivateInstance(classId.Get(), bitmapImage.GetAddressOf())))
{
// Handle failure
}