كيف يمكنني تمرير وظيفة بالرجوع إلى رد الاتصال بالتقرير في C ++ / CLI؟
-
23-08-2019 - |
سؤال
لدي بعض الكود الذي يتعامل مع ملفات البيانات والتقارير عن خطأ عند تشغيله في ورطة، ولكن أواجه مشكلة في العمل في كيفية إعطاء دالة رد اتصال صفي. إليك مثال سريع على نوع الشيء الذي أحاول تحقيقه:
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) );
}
};
لا تنتمي إلى StackOverflow