如何将现有的自定义SwapChainPanel从C ++ / CX转换为C ++ / WinRT

时间:2019-05-22 15:08:34

标签: c++-winrt

我正在尝试将现有的C ++ / CX代码转换为C ++ / WinRT,以便确定是否可以使我使用Clang编译该代码。但是,我很早就被困住了。

我需要转换的C ++ / CX代码用于构建Direct3D组件(基于SwapChainPanel),该组件最终用C#编写的Windows UWP应用程序中使用。我面临的问题是我只是无法将定制的SwapChainPanel转换为C ++ / WinRT。

代码如下:

namespace Why::Does::This::Not::Work
{
  [Windows::Foundation::Metadata::WebHostHidden]
  public ref class BaseView : public Windows::UI::Xaml::Controls::SwapChainPanel
  {
  protected private:
    BaseView();
    // Lots of other stuff
  };
}


namespace Why::Does::This::Not::Work
{
  [Windows::Foundation::Metadata::WebHostHidden]
  public ref class CustomView sealed : public BaseView
  {
  public:
    CustomView();
    // ...

    event AnimationEventHandler^ AnimationStarted;

  private protected:
    // Lots of private protected stuff
  };
}


namespace Why::Does::This::Not::Work
{
  [Windows::Foundation::Metadata::WebHostHidden]
  public ref class AnimationEventArgs sealed
  {
  public:
    AnimationEventArgs() {}

    AnimationEventArgs(int start, int end)
    {
      Start = start;
      End   = end;
    }

    property int Start;
    property int End;
  };

  [Windows::Foundation::Metadata::WebHostHidden]
  public delegate void AnimationEventHandler(Platform::Object^ sender, AnimationEventArgs^ e);
}

据我所能解释的文档,我需要按照文档If you're authoring a runtime class to be referenced in your XAML UI中所述进行操作。

因此,在我看来,我需要编写一个IDL文件才能生成所需的COM内容。但是,我什至无法编译框架IDL:

namespace Why
{
  namespace Does
  {
    namespace This
    {
      namespace Not
      {
        namespace Work
        {
          runtimeclass CustomView : Windows::UI::Xaml::Controls::SwapChainPanel
          {
            CustomView();
          }
        }
      }
    }
  }
}

尝试编译以上代码时,我得到的只是

error MIDL2025: [msg]syntax error [context]: expecting { near ":"
error MIDL2026: [msg]cannot recover from earlier syntax errors; aborting compilation

如果您将此问题视为愚蠢的问题,我深表歉意。我已经阅读了相应的文档,但是我只是无法理解使用C ++ / WinRT时的实际情况。我在C ++方面有丰富的经验,但在COM方面则只有零经验,这意味着除了了解C ++ / WinRT之外,其他所有内容都是直接的。

如果有人可以帮我将上述C ++ / CX代码翻译为C ++ / WinRT,将不胜感激。请不要仅将我指向文档,这无济于事。


编辑:

按如下所示修改示例IDL代码成功编译了它:

namespace Why
{
  namespace Does
  {
    namespace This
    {
      namespace Not
      {
        namespace Work
        {
          [default_interface]
          runtimeclass CustomView : Windows.UI.Xaml.Controls.SwapChainPanel
          {
            CustomView();
          }
        }
      }
    }
  }
}

但是,将用户控件暴露于另一种语言(在我的情况下为C#),例如从SwapChainPanel继承的一种语言,比在C ++ / CX中执行同一操作要复杂得多。有一个IDL很难处理,因为周围似乎没有任何复杂的样本。该IDL生成了几个我不确定要做什么的头文件,因为缺少文档并且样本稀疏。 C ++ / WinRT不适合胆小者,与C ++ / CX相比,它的复杂性要高得多。

在我看来,真正了解C ++ / WinRT是掌握COM的必要条件,因为与C ++ / CX相比,C ++ / WinRT在隐藏那些COM方面做得很差。相关内部。在处理DirectX时尤其如此。再加上本身很难处理的IDL和它的文档,可能足以启动并运行简单的示例,但在移植完整的C ++ / CX应用程序时却无济于事。

在C ++ / WinRT中使用C ++ / CX进行操作只是不经济的,我们将继续使用C ++ / CX,直到C ++ / WinRT变得更易用为止。消除对IDL的需求(请参阅https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/36095386-get-rid-of-idl-for-c-winrt-components)也将有所帮助。

如果没有使用Clang编译代码的希望,我什至不会考虑放弃C ++ / CX。 Microsoft不应奇怪C ++ / WinRT的采用速度很慢。如果他们真的想改变,就必须大幅降低进入门槛。

1 个答案:

答案 0 :(得分:2)

IDL中的完全限定类型名称使用句点(.)作为名称空间分隔符。有效的IDL文件如下所示:

namespace Why
{
  namespace Does
  {
    namespace This
    {
      namespace Not
      {
        namespace Work
        {
          runtimeclass CustomView : Windows.UI.Xaml.Controls.SwapChainPanel
          {
            CustomView();
          }
        }
      }
    }
  }
}

Microsoft Interface Definition Language 3.0 reference上有相当完整的文档。即便如此,从MIDL错误消息中弄清任何含义通常也很困难。