Pregunta

Tengo algo de código que se encarga de los archivos de datos e informa de un error cuando se mete en problemas, pero estoy teniendo problemas para saber cómo dar mi clase una función de devolución de llamada. Aquí está un ejemplo rápido de la clase de cosas que estoy tratando de lograr:

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 );
    }
};

... que tiene un problema:

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

Así que tengo la impresión de que estoy usando mis-o cosas malentendido. Tal vez hay una mejor manera de lograr esto?

¿Fue útil?

Solución

Es necesario crear el delegado explícitamente - y que necesita para aprobar la instancia asociada - en su caso, this - a ella:

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

Otros consejos

En caso de que a alguien le interesa, aquí está el código final (de trabajo):

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) );
    }
};
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top