2009-07-06 12 views
0

Ich habe einen Code, der Datendateien verarbeitet und einen Fehler meldet, wenn es Probleme gibt, aber ich habe Probleme herauszufinden, wie ich meiner Klasse eine Callback-Funktion geben kann. Hier ist ein kleines Beispiel für die Art von Sache, ich versuche zu erreichen:Wie kann ich eine Funktion als Referenz für einen Bericht Rückruf in C++/CLI übergeben?

public delegate void Reporter(System::String^ stringToReport); 

/// <summary> 
/// Simple file handler with callback options on error 
/// </summary> 
public ref class MyFileHandler 
{ 
private: 
    Reporter^ m_reporter; 

    void ReportError(String^ error) 
    { 
     if(m_reporter) 
     { 
      m_reporter(error); 
     } 
    } 

public: 
    MyFileHandler() 
    { 

    } 

    void SetErrorReporter(Reporter^ reporter) 
    { 
     m_reporter = reporter; 
    } 

    bool FailingOperation() 
    { 
     return false; 
    } 

    bool GetData() 
    { 
     bool succeeded = false; 

     // Do some operation that fails 
     succeeded = FailingOperation(); 

     if(succeeded == false) 
     { 
      ReportError("Gah, something bad happened!"); 
     } 

    } 
}; 


public ref class MyFileLoader 
{ 
private: 
    MyFileHandler m_mfh; 

    void ErrorHandler(String^ errorMsg) 
    { 
     System::Windows::Forms::MessageBox::Show(errorMsg); 
    } 

public: 
    MyFileLoader() 
    { 
     m_mfh.SetErrorReporter(&CallbackFunctionTests::MyFileLoader::ErrorHandler); 
    } 
}; 

..., die ein Problem hat:

1>CallbackTest.h(131) : error C3374: can't take address of 'CallbackFunctionTests::MyFileLoader::ErrorHandler' unless creating delegate instance 

So bekomme ich den Eindruck, ich bin falsch verwendet oder Dinge missverstehen. Vielleicht gibt es einen besseren Weg, dies zu erreichen?

Antwort

4

Sie müssen die Delegierten ausdrücklich erstellen - und Sie müssen die zugehörige Instanz weitergeben - in Ihrem Fall this - es:

m_mfh.SetErrorReporter(
    gcnew Reporter(this, &CallbackFunctionTests::MyFileLoader::ErrorHandler)); 
+0

+ 1/Akzeptiert: Ausgezeichnet - das hat es :-) –

0

Falls interessiert jemand, hier sind der letzte (in Betrieb) Code:

public delegate void Reporter(System::String^ stringToReport); 

/// <summary> 
/// Simple file handler with callback options on error 
/// </summary> 
public ref class MyFileHandler 
{ 
private: 
    Reporter^ m_reporter; 

    void ReportError(String^ error) 
    { 
     if(m_reporter) 
     { 
      m_reporter(error); 
     } 
    } 

public: 
    MyFileHandler() 
    { 

    } 

    void SetErrorReporter(Reporter^ reporter) 
    { 
     m_reporter = reporter; 
    } 

    bool FailingOperation() 
    { 
     return false; 
    } 

    bool GetData() 
    { 
     bool succeeded = false; 

     // Do some operation that fails 
     succeeded = FailingOperation(); 

     if(succeeded == false) 
     { 
      ReportError("Gah, something bad happened!"); 
     } 

     return succeeded; 
    } 
}; 


public ref class MyFileLoader 
{ 
private: 
    MyFileHandler m_mfh; 

    void ErrorHandler(String^ errorMsg) 
    { 
     System::Windows::Forms::MessageBox::Show(errorMsg); 
    } 

public: 
    MyFileLoader() 
    { 
     m_mfh.SetErrorReporter(gcnew Reporter(this, &CallbackFunctionTests::MyFileLoader::ErrorHandler)); 
    } 
};