2010-01-22 2 views
5

Ho seguito le "esercitazioni" su come esporre un framework .NET tramite COM (http://msdn.microsoft.com/en-us/library/zsfww439.aspx e http://msdn.microsoft.com/en-us/library/bd9cdfyx.aspx). Tutto funziona tranne la parte degli eventi. Quando aggiungo eventi per l'interfaccia C# viene generato il seguente codice C++:Registrazione di gestori per evento COM .NET in C++

struct __declspec(uuid("...")) 
_MessageEventHandler : IDispatch 
{}; 

struct __declspec(uuid("...")) 
IConnection : IDispatch 
{ 
    virtual HRESULT __stdcall add_MessageEvent (
    /*[in]*/ struct _MessageEventHandler * value) = 0; 
    virtual HRESULT __stdcall remove_MessageEvent (
    /*[in]*/ struct _MessageEventHandler * value) = 0; 
} 

Il problema è che non ho trovato alcuna informazione su come utilizzare questo in C++. Devo derivare da _MessageEventHandler e attuare operator()? O qualcos'altro interamente?

(Si noti che per il momento sto anche cercando l'approccio più documentata di utilizzare IConnectionPointContainer e IConnectionPoint.)

+0

Probabilmente ci si aspetta di derivare da '_MessageEventHandler' e ricevere una chiamata su' IDispatch :: Invoke() 'per l'evento - ma la domanda è con quale' DISPID'? –

risposta

2

E 'stato molto tempo da quando ho usato COM e in quel momento mi è stato utilizzando Visual C++ 6.0 . Ricordo che l'implementazione dei sink per i punti di connessione COM non era un processo semplice. Esistono diversi modi per implementarli, a seconda che si utilizzi MFC o ATL. Forse ci sono modi più semplici ora. Qui ci sono un paio di link che può aiutare a:

Code Project - Sinking events from managed code in unmanaged C++
Code Project - COM - gran numero di articoli su COM
Code Project - Handling COM Events in a Console Application
Code Project - Handling COM Events in a Console Application, Part II

+0

Thx. Il primo link mi ha mostrato le "parti mancanti" :-) –

1

IDispatch è usato per il runtime lingue vincolanti come VB, si sarebbe normalmente non è necessario farlo per un linguaggio fortemente tipizzato come C#.

Quando si chiama un metodo tramite IDispatch, ciò che effettivamente si fa è costruire un array contenente l'id del metodo (chiamato dispid) e i parametri, quindi passarlo a una funzione che ricerca attraverso una tabella di metodi da dispid, quando trova uno, usa il tuo array di parametri per costruire un callstack e poi chiama il metodo. (Questa è una semplificazione eccessiva, ovviamente).

Quindi sapere che una classe implementa IDispatch non ti dice quasi nulla.

Quindi questo è un falso vantaggio o manca la dichiarazione per le tabelle di invio di MessageEventHandler.

Non è affatto sorprendente che non si riesca a capire come implementare da questo, mancano alcune informazioni vitali.