2008-10-02 10 views
11

Ich benutze boost :: signal in einer nativen C++ Klasse, und ich schreibe jetzt einen .NET Wrapper in C++/CLI, so dass ich die nativen C++ - Callbacks als .NET-Ereignisse verfügbar machen kann. Wenn ich versuche, boost :: bind zu verwenden, um die Adresse einer Mitgliedsfunktion meiner verwalteten Klasse zu übernehmen, erhalte ich den Compilerfehler 3374, der besagt, dass ich die Adresse einer Mitgliedsfunktion nicht annehmen kann, wenn ich keine Delegateninstanz erstelle. Kann jemand eine Memberfunktion einer verwalteten Klasse mithilfe von boost :: bind binden?Wie man boost :: bind in C++/CLI verwendet um ein Mitglied einer verwalteten Klasse zu binden

Zur Verdeutlichung der folgende Beispielcode verursacht Compilerfehler 3374:

#include <boost/bind.hpp> 

public ref class Managed 
{ 
public: 
    Managed() 
    { 
     boost::bind(&Managed::OnSomeEvent, this); 
    } 

    void OnSomeEvent(void) 
    { 
    } 
}; 

Antwort

10

Während Ihre Antwort funktioniert, stellt sie einige Ihrer Implementierung der Welt (Managed :: OnSomeEvent). Wenn Sie das Ereignis OnChange notgedrungen durch den Aufruf OnSomeEvent() zu erhöhen, um der Lage sein, die Menschen nicht wollen, können Sie Ihre Managed-Klasse wie folgt aktualisieren (basierend auf this advice):

public delegate void ChangeHandler(void); 
typedef void (__stdcall *ChangeCallback)(void); 

public ref class Managed 
{ 
public: 
    Managed(Native* Nat); 
    ~Managed(); 

    event ChangeHandler^ OnChange; 

private: 
    void OnSomeEvent(void); 
    Native* native; 
    Callback* callback; 
    GCHandle gch; 
}; 

Managed::Managed(Native* Nat) 
: native(Nat) 
{ 
    callback = new Callback; 

    ChangeHandler^ handler = gcnew ChangeHandler(this, &Managed::OnSomeEvent); 
    gch = GCHandle::Alloc(handler); 
    System::IntPtr ip = Marshal::GetFunctionPointerForDelegate(handler); 
    ChangeCallback cbFunc = static_cast<ChangeCallback>(ip.ToPointer()); 

    *callback = native->RegisterCallback(boost::bind<void>(cbFunc)); 
} 

Managed::~Managed() 
{ 
    native->UnregisterCallback(*callback); 
    delete callback; 
    if (gch.IsAllocated) 
    { 
     gch.Free(); 
    } 
} 

void Managed::OnSomeEvent(void) 
{ 
    OnChange(); 
} 

Beachten Sie die alternative bind<R>() Form das ist benutzt.

+0

Ich versuche, etwas ähnliches hier zu tun. Gibt es einen Ratschlag, um Strings zum/vom Callback zu übergeben? http://stackoverflow.com/q/42304020/15369 –

4

Nach etwas mehr googeln, fand ich endlich einen nice blog post darüber, wie dies zu tun. Der Code in diesem Beitrag war ein wenig mehr als ich brauchte, aber das Hauptnugget war, eine globale freie Funktion zu verwenden, die ein Argument des verwalteten in einem gcroot <> Vorlage eingewickelten Zeigers nimmt. Ein Beispiel finden Sie unter SomeEventProxy (...) im folgenden Code. Diese Funktion dreht sich dann um und ruft das verwaltete Mitglied auf, das ich zu binden versuchte. Meine Lösung erscheint unten für zukünftige Referenz.

Verwandte Themen