Wie Boost verwenden :: bind in C ++ / CLI ein Mitglied einer verwalteten Klasse zu binden
-
03-07-2019 - |
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)
{
}
};
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.