2012-10-02 2 views
1

WRL을 사용하여 winrt 구성 요소를 만들 때 ABI::Windows::xxx 네임 스페이스 만 사용할 수 있으며 WRL에서 Windows::UI::Xaml::Media::Imaging 네임 스페이스를 사용할 수 없습니다.WRL을 사용하여 build-in winrt 구성 요소를 반환하는 방법은 무엇입니까?

그런 다음 반환 값으로 빌드 윈인 구성 요소를 만드는 방법은 무엇입니까?

  • 글로벌 네임 스페이스 (예 : Windows::Foundation)
  • ABI 네임 스페이스에 뿌리를 둔 사람들을 뿌리들 (예를 들어 ABI::Windows::Foundation)

:

// 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); 
    } 
} 

답변

5

네임 스페이스의 두 가지가 있습니다 각각의 내용은 "동일합니다." 예를 들어, Windows::Foundation::IUriRuntimeClassABI::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 
} 
+0

을 고마워요.하지만 UI 스레드에서 생성 된 다른 스레드에서 ActivateInstance를 호출하면 RPC_E_WRONG_THREAD를 반환하고 인스턴스를 만들지 못했습니다. 그러나 나는 또한 다른 스레드에서'CreateStreamOverRandomAccessStream'을 호출하려고합니다. COM 객체를 생성하는 것과 유사하지만 잘 동작 할 수 있다고 생각합니다. 왜 그런지 알아? – user1713871