Pergunta

Eu tenho algum código que lida com arquivos de dados e relata um erro quando ele é executado em apuros, mas estou tendo problemas para trabalhar fora como dar minha aula de uma função de chamada de retorno. Aqui está um exemplo rápido do tipo de coisa que eu estou tentando alcançar:

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 tem um problema:

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

Assim, tenho a impressão que estou mis-usando ou mal-entendido coisas. Talvez haja uma maneira melhor de conseguir isso?

Foi útil?

Solução

Você precisa criar o delegado explicitamente - e você precisa passar a instância associada - no seu caso, this - a ele:

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

Outras dicas

No caso de qualquer pessoa interessada, aqui está o código final (trabalho):

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top