如何在 C++/CLI 中通过引用传递函数以进行报告回调?

发布于 2024-07-26 03:20:18 字数 1470 浏览 3 评论 0原文

我有一些代码可以处理数据文件并在遇到问题时报告错误,但我无法弄清楚如何为我的类提供回调函数。 这是我想要实现的那种事情的一个简单例子:

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

所以我觉得我误用或误解了事物。 也许有更好的方法来实现这一目标?

I have some code which handles data files and reports an error when it runs into trouble, but I'm having trouble working out how to give my class a callback function. Here's a quick example of the sort of thing I'm trying to achieve:

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

...which has a problem:

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

So I get the impression I'm mis-using or misunderstanding things. Maybe there's a better way of achieving this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╭⌒浅淡时光〆 2024-08-02 03:20:18

您需要显式创建委托 – 并且需要将关联的实例 – 在您的情况下为 this – 传递给它:

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

You need to create the delegate explicitly – and you need to pass the associated instance – in your case, this – to it:

m_mfh.SetErrorReporter(
    gcnew Reporter(this, &CallbackFunctionTests::MyFileLoader::ErrorHandler));
拒绝两难 2024-08-02 03:20:18

如果有人感兴趣,这里是最终(工作)代码:

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

In case anyone's interested, here's the final (working) 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) );
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文