从wrlcom组件获取托管回调
Getting a managed callback from a WRL COM component
背景(或者,看看我自己走了多远!)
我从Windows 8媒体扩展示例开始。我使用灰度示例作为起点,学习如何将值从托管代码传递到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委托。
这个页面让我相信我应该能够在COM世界中声明一个WinRT委托,并且能够从c#中传递一个相同类型的委托(参见最后的第三项)。酷——看起来很容易。到目前为止,我最好的尝试是在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编译。
我说错话了吗?我应该让我的GrayscaleEffect类是使用c++/CX的WinRT运行时类吗?也许我们在这里冒险进入"新问题"领域,但是当我试图在c++/CX中使用WinRT类实现IMFTransform时,我得到
错误C2811: 'GrayscaleRT::Class1':不能从'IMFTransform'继承,一个ref类只能从ref类或接口类继承
一个更好的问题:我能在这里传递一个委托吗?我觉得我应该能够做到,只要我知道WRL模板的神奇组合就可以了。
看起来这就是答案。在WRL中,您可以像这样在idl中声明一个事件:
[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(NTDDI_WIN8)]
delegate HRESULT WhateverEvent();
请参阅添加一个在计算素数时触发的事件部分
我的问题是,我最初不明白我不是使用c++/cx。我使用常规c++和WRL, WRL是一个类似于ATL的模板库,使WinRT编程更容易,并且不使用非标准语言扩展。
一旦我理解了这一点,找到一个使用WRL的事件处理程序示例就相对容易了
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 如何使用软化工具包从 OPC UA 服务器异步读取操作回调中的数据值响应中获取 NodeId 详细信息
- 我可以使用谷歌 v8 在回调函数中获取 JavaScript 函数C++源文本吗?
- 获取要在C++中动态调用的回调函数的地址
- 在通过 P/Invoke 获取的 C++ 结构上设置 C# 回调
- 如何在 Windows 进程回调中断开连接时获取设备信息(硬件 ID)
- 从TLS回调中获取线程信息
- C 从回调函数中的对话框获取并设置值
- c++:当回调不提供用户参数时如何获取上下文?
- db耿-获取命令的输出,而不是通过回调
- 从wrlcom组件获取托管回调
- 如何在对象上获取一个方法,以便将其作为C样式回调传递