É possível para a classe nativa consumir evento .NET?
Pergunta
Qualquer idéia de como inicializar delegado .NET que aponta para método de instância de classe 'mista'?
Eu tenho 'misto' C ++ classe como este:
class CppMixClass
{
public:
CppMixClass(void){
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(&UpdateHealthState);
}
~CppMixClass(void);
void UpdateState(System::Object^ sender, DotNetClass::StateEventArgs^ e){
//doSmth
}
}
DotNetClass é implementado em C #, e declaração de método é OK com delegado. Esta linha gera erro:
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(&UpdateHealthState);
error C2276: '&' : illegal operation on bound member function expression
Alguém tem uma pista sobre um problema? Talvez coz classe CppMixClass não é uma pura classe .NET (ref)?
Eu tenho isso para o trabalho quando UpdateHealthState é método estático, mas eu preciso de ponteiro para método de instância.
Eu tentei smth como:
dotNETclass->StateChanged += gcnew DotNetClass::ServiceStateEventHandler(this, &UpdateHealthState);
Mas isso obviamente não trabalho coz isso não é ponteiro (punho) para .NET (ref) classe, (System :: Object).
ServiceStateEventHandler é definida em C # como:
public delegate void ServiceStateEventHandler(object sender, ServiceStateEventArgs e);
Thanx por ler este:)
Solução
Eu encontrei resposta para isso (claro por Nishant Sivakumar, o homem parece ter respostas para todas as minhas C ++ / CLI interoperabilidade problemas relacionados):
http://www.codeproject.com/KB/mcpp /CppCliSupportLib.aspx?display=Print
Resposta está localizado no "msclr / event.h" cabeçalho, onde macros para delegados em classes nativas são definidos.
código de Nish é o seguinte:
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);
}
};
Outras dicas
Somente os tipos de .NET podem usar eventos. Sugiro a criação de uma nova classe gerenciada que manipula o evento, e compor essa classe dentro CppMixClass, e passá-lo um ponteiro para CppMixClass durante a construção. Sua classe manipulação de eventos gerenciado pode, em seguida, chamar uma função em CppMixClass quando se lida com um evento.