2014-10-27 80 views
-1

我正在尝试编写一个使用C++ DLL的基于C#的WPF应用程序。 C#应用程序用于用户界面,它具有WPF的所有优点。 C++ DLL使用Win32函数(例如枚举窗口)。从C++中处理事件遇到问题需要在C#中处理

现在我想让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': improper use of 'event'; must be a member of a compatible event source

C2059: syntax error: 'event'

C3861: 'wE': identifier not found

+0

* event *关键字必须出现在'public ref class'内部。此外,您还必须使用托管的'value struct'而不是原生的'struct'来允许C#代码访问结构成员。 – 2014-10-27 18:50:53

回答

0

你的事件需要是一些管理成员类,可能是静态的。例如:

#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类型。

+1

使用'value struct'而不是'struct'。 – ArthurCPPCLI 2014-10-28 12:43:57

+0

@JanBöhm - 回答最新的建议来自ArthurCPPCLI。 – dbc 2014-10-28 17:19:14