C# 从WRL COM组件获取托管回调

C# 从WRL COM组件获取托管回调,c#,c++,com,delegates,windows-runtime,C#,C++,Com,Delegates,Windows Runtime,背景或者,看看我自己走了多远 我从第一站开始。我使用灰度示例作为起点,学习如何将值从托管代码传递到COM对象,以及如何将值从COM对象传递回托管代码。在我的IDL文件中,我有一个完全取自示例的GrayscaleEffect类和一个自定义接口,该接口应该允许我在c世界中查询字符串 IDL文件: namespace GrayscaleTransform { [version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]

背景或者,看看我自己走了多远

我从第一站开始。我使用灰度示例作为起点,学习如何将值从托管代码传递到COM对象,以及如何将值从COM对象传递回托管代码。在我的IDL文件中,我有一个完全取自示例的GrayscaleEffect类和一个自定义接口,该接口应该允许我在c世界中查询字符串

IDL文件:

namespace GrayscaleTransform
{
    [version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]
    interface MyInterface : IInspectable {
        HRESULT GetMsg([out] HSTRING *message);
    }

    [version(NTDDI_WIN8)]
    runtimeclass GrayscaleEffect {
        interface Windows.Media.IMediaExtension;
        interface MyInterface;
    }
}
我的GrayscaleEffect类实现实现GetMsg以返回字符串Woozle

有关委员会:

cap = new MediaCapture();
await cap.InitializeAsync();

previewElement1.Source = cap;
await cap.StartPreviewAsync();

PropertySet props = new PropertySet();
await cap.AddEffectAsync(
    Windows.Media.Capture.MediaStreamType.VideoPreview,
    "GrayscaleTransform.GrayscaleEffect",
    props);

if (this.props.ContainsKey("ref"))
{
    var augGui = (GrayscaleTransform.MyInterface)this.props["ref"];
    string message;
    augGui.GetMsg(out message);
}
在调用GetMsg之后,我可以看到消息包含字符串Woozle,就像我期望的那样-非常好

问题

现在我想做一些更有趣的事情。我想实现一个方法,让我将委托从C传递到COM,而不是让我将字符串从COM传递到C。我想让MFT类每10个视频帧调用一次这个方法,或者其他什么-这部分并不重要。我希望我的接口有一个名为SubscribeEvent的方法,该方法将委托作为参数。目前,它可以是不带参数的void委托

这让我相信我应该能够在COM世界中声明一个WinRT委托,并且能够从C中传递一个相同类型的委托。参见结尾的第三项。酷-似乎很容易。到目前为止,我在idl中的最佳尝试如下:

delegate void CallbackMethod();

[version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]
interface MyInterface : IInspectable {
    HRESULT Subscribe(CallbackMethod cb);
}
不幸的是,这会导致一个错误-似乎与委托回调方法的声明有关:

错误MIDL9008:内部编译器问题-有关如何找到解决方法的建议,请参阅文档

编辑 这是显而易见的。这种语法是C++/cx的东西。仔细检查后,我没有打开C++/CX扩展。这是一个WRL项目,这意味着它是普通的味道C++模板魔术。 我还试图通过实现IConnectionPoint接口来连接事件,但当我包含OCIdl.h时,我得到一个编译错误,即无法为ARM编译桌面组件

问题 我找错树了吗?我应该使用C++/CX将我的GrayscaleEffect类设置为WinRT运行时类吗?也许我们正在冒险进入一个新的问题领域,但当我试图用C++/CX中的WinRT类实现IMFTTransform时,我得到了

错误C2811:“GrayscaleRT::Class1”:无法从“imftTransform”继承,ref类只能从ref类或接口类继承

一个更好的问题: 这个怎么样:我可以在这里传递一个代表吗?我觉得我应该能够做到,只要我知道WRL模板的神奇组合就能让它工作。

看起来是这样的。在WRL中,您在idl中声明一个事件,如下所示:

[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(NTDDI_WIN8)]
delegate HRESULT WhateverEvent();
请参阅添加在计算质数时激发的事件部分

我的问题是,起初我不明白我没有使用c++/cx。我使用的是规则的C++,它是一个类似于ATL的模板库,它使WRET编程更容易,并且不使用非标准语言扩展。 一旦我了解了这一点,就可以相对容易地找到使用WRL的事件处理程序示例