我在Windows运行时组件(用C#编写)中有一个类来引发事件 我无法弄清楚如何在引用该组件的C ++ / CX应用程序中订阅这些事件。
C#代码(在Windows运行时组件中):
public sealed class Messenger {
private EventRegistrationTokenTable<EventHandler<MessageReceivedEventArgs>> messageReceivedTokenTable;
public event EventHandler<MessageReceivedEventArgs> MessageReceived
{
add
{
return EventRegistrationTokenTable<EventHandler<MessageReceivedEventArgs>>
.GetOrCreateEventRegistrationTokenTable(ref this.messageReceivedTokenTable)
.AddEventHandler(value);
}
remove
{
EventRegistrationTokenTable<EventHandler<MessageReceivedEventArgs>>
.GetOrCreateEventRegistrationTokenTable(ref this.messageReceivedTokenTable)
.RemoveEventHandler(value);
}
}
internal void OnMessageReceived(string message, string location)
{
EventHandler<MessageReceivedEventArgs> temp =
EventRegistrationTokenTable<EventHandler<MessageReceivedEventArgs>>
.GetOrCreateEventRegistrationTokenTable(ref this.messageReceivedTokenTable)
.InvocationList;
temp(this, new MessageReceivedEventArgs(message, location));
}
}
MessageReceivedEventArgs
是:
public sealed class MessageReceivedEventArgs : object
{
public MessageReceivedEventArgs(string message, string location)
{
this.Message = message;
this.SenderLocation = location;
}
public string Message { get; set; }
public string SenderLocation { get; set; }
}
请注意,根据MSDN,它从对象而不是EventArgs下降。
然后在C ++中:
msngr = ref new Messenger();
msngr->MessageReceived += ?????????
+=
之后以及相关方法(以及其他任何地方 - 在C#和/或C ++中)应该怎样才能在C ++应用程序中接收消息?
我尝试了各种各样的事情,我遇到的各种编译器警告都无法指出我的解决方案。
我发现使用用C#编写但在C ++应用程序中使用的Windows运行时组件的所有示例都很简单,只显示使用属性和调用方法。我可以毫无问题地做到这两点。我是在C#中使用C#订阅一个事件的例子。
答案 0 :(得分:4)
必须创建一个代理来使用这些类型。
确实是你的问题,需要一个COM代理/存根来将你的MessageReceivedEventArgs类从C#编组到C ++ / CX。是的,记录很差。我会尝试解释这个过程。开始使用此WinRT sample,它演示了设置解决方案以获取所需代理的方法,并完全按照您的要求进行操作。
起点是ProxyStubForWinRTComponents_server项目,这是一个声明共享类的C#项目。该项目的重要部分是Post-Build事件,它看起来像这样:
call "$(DevEnvDir)..\..\VC\vcvarsall.bat" x86
winmdidl /outdir:"$(ProjectDir)\" "$(TargetPath)"
第一个语句设置运行SDK工具的环境。第二步运行winmdidl.exe,这是一个完全未记录的构建工具,它将项目生成的.winmd文件反编译为IDL文件,然后编译。此构建步骤的输出为:
接下来看看ProxyStubsForWinRTComponentsPS项目,该项目是构建代理/存根DLL的项目。它使用winmdidl.exe生成的文件,唯一添加的文件是声明DLL导出的.def文件。 COM调用那些使用代理,您可以按原样使用该文件。最好按原样使用此项目,只更改文件名称,这样您就可以正确编译所有编译器和链接器。
毫无疑问,不愉快且有很多方法可以解决这个问题。希望它有所帮助。
答案 1 :(得分:0)
假设您在C ++ ref类中编写此代码,假设使用CPPClass,您的代码将如下所示:
CPPClass::MyEventHandler(Platform::Object^ obj, MessageReceivedEventArgs^ args)
{
// handler code
}
CPPClass::SomeMethod()
{
msngr = ref new Messenger(this->SpecifedServer->Text);
msngr->MessageReceived += ref new EventHandler<MessageReceivedEventArgs^>(this, &CPPClass::MyEventHandler);
}
=================
顺便说一句,下面是一个类似的示例代码,对我来说很合适:
在C#中定义类和事件:
namespace WindowsRuntimeComponent3
{
public sealed class MyEventsArgs
{
}
public sealed class Class1
{
public Class1()
{
}
public event EventHandler<MyEventsArgs> MyEvent;
}
}
在C ++中使用事件:
App::App()
{
InitializeComponent();
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
auto obj = ref new WindowsRuntimeComponent3::Class1();
obj->MyEvent += ref new EventHandler<WindowsRuntimeComponent3::MyEventsArgs^>(this, &App::MyEventHandler);
}
=================
答案 2 :(得分:0)
此方案的官方文档可在MSDN上找到:Raising Events in Windows Runtime Components