كيف يمكنني تمرير وظيفة بالرجوع إلى رد الاتصال بالتقرير في C ++ / CLI؟

StackOverflow https://stackoverflow.com/questions/1086378

سؤال

لدي بعض الكود الذي يتعامل مع ملفات البيانات والتقارير عن خطأ عند تشغيله في ورطة، ولكن أواجه مشكلة في العمل في كيفية إعطاء دالة رد اتصال صفي. إليك مثال سريع على نوع الشيء الذي أحاول تحقيقه:

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

... الذي لديه مشكلة:

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

لذلك أحصل على الانطباع الذي أتخلص منه أو سوء فهم الأشياء. ربما هناك طريقة أفضل لتحقيق هذا؟

هل كانت مفيدة؟

المحلول

تحتاج إلى إنشاء المفوض صراحة - وتحتاج إلى تمرير المثيل المرتبط - في قضيتك، this - لذلك:

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

نصائح أخرى

في حالة مهتمة أي شخص، إليك الرمز النهائي (العمل):

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) );
    }
};
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top