背景(或者,看看我走了多远!)
我从Windows 8 Media Extension Sample开始。我正在使用灰度示例作为起点来学习如何将值从托管代码传递到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”
相关的c#:
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委托。
This page让我相信我应该能够在COM世界中声明一个WinRT委托,并且能够从C#传递相同类型的委托(参见最后的第3个项目)。酷 - 看起来很容易。到目前为止,我最好的尝试在idl中是这样的:
delegate void CallbackMethod();
[version(NTDDI_WIN8), uuid(553B5684-4C22-4D21-8638-1E7D86D84F10)]
interface MyInterface : IInspectable {
HRESULT Subscribe(CallbackMethod cb);
}
不幸的是,这会导致错误 - 似乎与委托CallbackMethod的声明有关:
错误MIDL9008:内部编译器问题 - 有关如何查找变通方法的建议,请参阅文档。
修改 这一点很明显。该语法是C ++ / cx的东西。经过仔细检查,我没有打开C ++ / CX扩展。这是一个WRL项目,这意味着它具有模板魔术的常规风格c ++。
我还尝试通过实现IConnectionPoint接口来连接事件,但是当我包含OCIdl.h时,我得到一个编译错误,即无法为ARM编译桌面组件。
问题 我在这里吠叫错了吗?我应该使用C ++ / CX使我的GrayscaleEffect类成为WinRT运行时类吗?也许我们冒险进入“新问题”领域,但是当我尝试用C ++ / CX中的WinRT类实现IMFTransform时,我得到了
错误C2811:'GrayscaleRT :: Class1':不能从'IMFTransform'继承,ref类只能从ref类或接口类继承
更好的问题: 怎么样:我可以在这里通过代表吗?如果只有我知道WRL模板的神奇组合才能使它工作,我就像我应该能够一样。
答案 0 :(得分:0)
看起来像this is the answer。在WRL中,您在idl中声明一个事件,如下所示:
[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(NTDDI_WIN8)]
delegate HRESULT WhateverEvent();
参见添加在计算素数时触发的事件部分
我的问题是我最初不明白我不是使用c ++ / cx。我使用常规c ++和WRL,这是一个类似于ATL的模板库,它使WinRT编程更容易,并且不使用非标准语言扩展。
一旦我明白了,使用WRL
找到一个事件处理程序的例子相对容易