Есть идеи, как инициализировать делегат .NET, который указывает на метод из экземпляра «смешанного» класса?
У меня есть «смешанный» класс C++:
class CppMixClass
{
public:
CppMixClass(void){
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(&UpdateHealthState);
}
~CppMixClass(void);
void UpdateState(System::Object^ sender, DotNetClass::StateEventArgs^ e){
//doSmth
}
}
DotNetClass реализован на C#, и объявление метода подходит для делегата. Эта строка генерирует ошибку:
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(&UpdateHealthState);
error C2276: '&' : illegal operation on bound member function expression
Кто-нибудь знает о проблеме? Может быть, класс CppMixClass не является чистым классом .NET (ref)?
Я получил это, чтобы работать, когда UpdateHealthState является статическим методом, но мне нужен указатель на метод экземпляра.
Я пробовал что-то вроде:
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(this, &UpdateHealthState);
Но это явно не работает, потому что это не указатель (дескриптор) на класс .NET (ref) (System :: Object).
ServiceStateEventHandler определяется в C# как:
public delegate void ServiceStateEventHandler(object sender, ServiceStateEventArgs e);
Спасибо, что прочитали это :)





Только типы .NET могут использовать события. Я предлагаю создать новый управляемый класс, который обрабатывает событие, и скомпоновать этот класс в CppMixClass, и передать ему указатель на CppMixClass во время построения. Затем ваш управляемый класс обработки событий может вызывать функцию в CppMixClass при обработке события.
Я только что нашел ответ на это (конечно, Нишант Сивакумар, у человека, похоже, есть ответы на все мои проблемы, связанные с взаимодействием с C++ / CLI):
http://www.codeproject.com/KB/mcpp/CppCliSupportLib.aspx?display=Print
Ответ находится в заголовке «msclr / event.h», где определены макросы для делегатов в собственных классах.
Код Ниша следующий:
class Demo5
{
msclr::auto_gcroot<FileSystemWatcher^> m_fsw;
public:
// Step (1)
// Declare the delegate map where you map
// native method to specific event handlers
BEGIN_DELEGATE_MAP(Demo5)
EVENT_DELEGATE_ENTRY(OnRenamed, Object^, RenamedEventArgs^)
END_DELEGATE_MAP()
Demo5()
{
m_fsw = gcnew FileSystemWatcher("d:\\tmp");
// Step (2)
// Setup event handlers using MAKE_DELEGATE
m_fsw->Renamed += MAKE_DELEGATE(RenamedEventHandler, OnRenamed);
m_fsw->EnableRaisingEvents = true;
}
// Step (3)
// Implement the event handler method
void OnRenamed(Object^, RenamedEventArgs^ e)
{
Console::WriteLine("{0} -> {1}",e->OldName, e->Name);
}
};