Проблемы с вызовом событий из C ++ для обработки в C #

Я пытаюсь написать приложение WPF на основе C #, которое использует C ++ DLL. Приложение C # предназначено для пользовательского интерфейса и обладает всеми преимуществами WPF. C ++ DLL использует функции Win32 (например, для перечисления окон).

Теперь я хочу, чтобы библиотека C ++ вызывала событие, которое можно обработать в приложении C #. Это то, что я пробовал (на основе эту статью):

//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': идентификатор не найден


person Jan Böhm    schedule 27.10.2014    source источник
comment
Ключевое слово event должно появиться внутри public ref class. Кроме того, вы должны использовать управляемый value struct вместо собственного struct, чтобы код C # имел доступ к элементам структуры.   -  person Hans Passant    schedule 27.10.2014


Ответы (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);
        }
};

Обновить

Если вам нужно преобразовать ваш неуправляемый HWND в IntPtr, поскольку _ 4_ - это стандартная подпись P / Invoke для HWND в 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.

person dbc    schedule 27.10.2014
comment
используйте value struct вместо struct. - person ArthurCPPCLI; 28.10.2014
comment
@Jan Böhm - ответ обновлен предложением ArthurCPPCLI. - person dbc; 28.10.2014