2

当我使用 WRL 创建 winrt 组件时,问题是我只能使用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);
    }
}
4

1 回答 1

8

有两组命名空间:

  • 那些根植于全局命名空间的(例如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
}
于 2012-10-02T17:16:16.163 回答