manejo - socket en c++ cliente servidor
Proporcionar una implementación de IDispatch para un cliente de punto de conexión (4)
Escribí un servidor de COM DLL inproc simple con un único objeto COM simple. El objeto COM implementa un punto de conexión.
Sé cómo crear un cliente ATL que se deriva de IDispEventImpl
, y utiliza un mapa de sumidero para simplificar este proceso.
Pero, para propósitos de demostración, me gustaría crear una aplicación de consola win32 que use una clase que llame a mi objeto COM simple, y que luego actúe como un receptor de puntos de conexión.
No tengo idea de cómo proporcionar una implementación de IDispatch
: ¿alguien puede recomendar documentación sobre esto, ya que no puedo encontrar ninguno (tengo ATL Internals, pero parece que esto no cubre lo que necesito).
Aquí está la clase que ya tengo:
#pragma once
#include <iostream>
using namespace std;
// Because we''re implementing a connection points sink (_IPogFarmEvents)
// in a non-ATL class, we must provide implementations for IUnknown and IDispatch.
class KidWithAPogFarm : public _IPogFarmEvents
{
private:
DWORD m_dwRefCount;
LONG m_lNumPogs;
public:
KidWithAPogFarm() :
m_dwRefCount (0),
m_lNumPogs (0)
{
}
~KidWithAPogFarm()
{
}
// -- IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
{
if (iid == DIID__IPogFarmEvents)
{
m_dwRefCount++;
*ppvObject = (void *)this;
return S_OK;
}
if (iid == IID_IUnknown)
{
m_dwRefCount++;
*ppvObject = (void *)this;
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef()
{
m_dwRefCount++;
return m_dwRefCount;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG l;
l = m_dwRefCount--;
if ( 0 == m_dwRefCount)
delete this;
return l;
}
// -- IDispatch
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )
{
return E_NOTIMPL;
}
STDMETHODIMP Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
{
return E_NOT_IMPL;
}
// -- IAntFarmEvents
STDMETHODIMP OnFarmCreated(LONG lInitialPopulation)
{
m_lNumPogs = lInitialPopulation;
cout << "The kid has a pog farm with " << m_lNumPogs << " pogs " << endl;
return S_OK;
}
};
Como ya tienes ATL
, puedes examinar sus fuentes y ver cómo IDispatchImpl
hace todo eso. IDispatch
métodos de IDispatch
se implementan allí leyendo datos de la biblioteca de tipos en el mismo módulo, ya que es la forma más fácil y confiable cuando una biblioteca de tipos ya está presente.
También vale la pena señalar que es un tema bastante difícil para hacer una demostración: tendrás que escribir una gran cantidad de código que realmente no aporta ningún conocimiento. OMI estará mucho mejor si implementa una interfaz de eventos que no hereda de IDispatch
sino que hereda directamente de IUnknown
. Esto demostrará cómo funcionan los eventos sin tener que prestar demasiada atención al funcionamiento interno de IDispatch
.
Creo que la forma más fácil de hacerlo es a través de CreateStdDispatch
Puede usar esta implementación IDispatch.
No es exactamente lo que está buscando, pero FireBreath usa IDispatchEx y puntos de conexión para proporcionar un control ActiveX que se ejecuta en IE. Debido a que FireBreath es una abstracción para permitir que los complementos se escriban una vez y se usen en todos los principales navegadores, la interfaz de IDispatch debe escribirse a mano, incluidos los puntos de conexión.
El código puede ser un poco confuso, ya que hay una clase mixin con plantilla utilizada para proporcionar IDispatch y ConnectionPoints a dos clases diferentes de objetos COM, pero puede ser útil.
Ya has aceptado una respuesta, pero tal vez te ayude. Lamento no haber visto la pregunta antes.