【问题标题】:Trouble raising events from C++ to be handled in C#从 C++ 引发要在 C# 中处理的事件时遇到问题
【发布时间】:2014-10-27 18:39:44
【问题描述】:

我正在尝试编写一个使用 C++ DLL 的基于 C# 的 WPF 应用程序。 C# 应用程序用于用户界面,它具有 WPF 的所有优点。 C++ DLL 使用 Win32 函数(例如枚举窗口)。

现在我希望 C++ DLL 引发可以在 C# 应用程序中处理的事件。这是我尝试过的(基于this article):

//cpp file

#using <System.dll>

using namespace System;

struct WIN {
    HWND Handle;
    char ClassName;
    char Title;
};

delegate void wDel(WIN);
event wDel^ wE;
void GotWindow(WIN Window) {
    wE(Window);
}

当我尝试编译这段代码时,会抛出这些错误:

C3708: 'wDel': 不当使用 'event';必须是兼容事件源的成员

C2059:语法错误:“事件”

C3861:“wE”:未找到标识符

【问题讨论】:

  • event 关键字必须出现在 public ref class 中。此外,您必须使用托管 value struct 而不是本机 struct 以允许 C# 代码访问结构成员。

标签: c# events c++-cli eventhandler


【解决方案1】:

您的事件需要是某个托管类的成员,可能是静态的。例如:

#include "stdafx.h"
#include "windows.h"

using namespace System;

struct WIN {
    HWND Handle;
    char ClassName;
    char Title;
};

delegate void wDel(WIN);

ref class WindowEvents abstract sealed // abstract sealed ref class in c++/cli is like a static class in c#
{
    public:
        static event wDel^ wE;

        static void GotWindow(WIN Window) {
            wE(Window);
        }
};

更新

如果你需要convert your unmanaged HWND to an IntPtr,因为IntPtrstandard P/Invoke signature for an HWND in c#,你可以考虑如下:

#include "stdafx.h"
#include "windows.h"

using namespace System;

#pragma managed(push,off)

struct WIN {  // Unmanaged c++ struct encapsulating the unmanaged data.
    HWND Handle;
    char ClassName;
    char Title;
};

#pragma managed(pop)

public value struct ManagedWIN  // Managed c++/CLI translation of the above.
{
public:
    IntPtr Handle; // Wrapper for an HWND
    char   ClassName;
    char   Title;
    ManagedWIN(const WIN win) : Handle(win.Handle), ClassName(win.ClassName), Title(win.Title)
    {
    }
};

public delegate void wDel(ManagedWIN);

public ref class WindowEvents abstract sealed // abstract sealed ref class in c++/cli is like a static class in c#
{
    public:
        static event wDel^ wE;

    internal:
        static void GotWindow(WIN Window) {
            wE(ManagedWIN(Window));
        }
};

这里ManagedWIN 只包含安全的.Net 类型。

【讨论】:

  • 使用value struct 而不是struct
  • @Jan Böhm - 根据 ArthurCPPCLI 的建议更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多