Frage

Ich bin mit boost :: Signal in einer nativen C ++ Klasse, und ich jetzt einen .NET-Wrapper in C ++ / CLI Ich schreibe, so dass ich die native C ++ Rückrufe als .NET Ereignisse aussetzen kann. Wenn ich versuche, Schub zu verwenden :: bind die Adresse einer Memberfunktion meiner verwalteten Klasse zu nehmen, erhalte ich Compiler-Fehler 3374, sagte, dass ich die Adresse einer Elementfunktion nicht übernehmen kann, wenn ich eine Delegatinstanz erschaffe. Wer weiß, wie eine Elementfunktion einer verwalteten Klasse zu binden, mit boost :: bind?

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)
    {
    }
};
War es hilfreich?

Lösung

Während Ihre Antwort funktioniert, ist es einige Ihrer Implementierung in die Welt setzt (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 diese Beratung ):

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, die verwendet wird.

Andere Tipps

Nach etwas mehr googeln, fand ich endlich ein

scroll top