openmedialibrary_platform_w.../Lib/site-packages/win32com/include/PythonCOMServer.h

163 lines
6.4 KiB
C
Raw Normal View History

2016-04-14 19:54:42 +00:00
#ifndef __PYTHONCOMSERVER_H__
#define __PYTHONCOMSERVER_H__
// PythonCOMServer.h :Server side COM support
#include <Python.h>
#define DLLAcquireGlobalLock PyWin_AcquireGlobalLock
#define DLLReleaseGlobalLock PyWin_ReleaseGlobalLock
void PYCOM_EXPORT PyCom_DLLAddRef(void);
void PYCOM_EXPORT PyCom_DLLReleaseRef(void);
// Use this macro at the start of all gateway methods.
#define PY_GATEWAY_METHOD CEnterLeavePython _celp
class PyGatewayBase;
// Gateway constructors.
// Each gateway must be able to be created from a "gateway constructor". This
// is simply a function that takes a Python instance as as argument, and returns
// a gateway object of the correct type. The MAKE_PYGATEWAY_CTOR is a helper that
// will embed such a constructor in the class - however, this is not necessary -
// _any_ function of the correct signature can be used.
typedef HRESULT (* pfnPyGatewayConstructor)(PyObject *PythonInstance, PyGatewayBase *, void **ppResult, REFIID iid);
HRESULT PyCom_MakeRegisteredGatewayObject(REFIID iid, PyObject *instance, PyGatewayBase *base, void **ppv);
// A version of the above which support classes being derived from
// other than IUnknown
#define PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, gatewaybaseclass) \
public: \
static HRESULT classname::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *unkBase, void **ppResult, REFIID iid) { \
if (ppResult==NULL) return E_INVALIDARG; \
classname *newob = new classname(pPyInstance); \
newob->m_pBaseObject = unkBase; \
if (unkBase) unkBase->AddRef(); \
*ppResult = newob->ThisAsIID(iid); \
return *ppResult ? S_OK : E_OUTOFMEMORY; } \
protected: \
virtual IID GetIID(void) { return theIID; } \
virtual void *ThisAsIID(IID iid) {if (this==NULL) return NULL;if (iid==theIID) return (IInterface *)this; else return gatewaybaseclass::ThisAsIID(iid);} \
STDMETHOD_(ULONG,AddRef)(void) {return gatewaybaseclass::AddRef();} \
STDMETHOD_(ULONG,Release)(void) {return gatewaybaseclass::Release();} \
STDMETHOD(QueryInterface)(REFIID iid, void ** obj) {return gatewaybaseclass::QueryInterface(iid, obj);};
// This is the "old" version to use, or use it if you derive
// directly from PyGatewayBase
#define PYGATEWAY_MAKE_SUPPORT(classname, IInterface, theIID) \
PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, PyGatewayBase)
#define GET_PYGATEWAY_CTOR(classname) classname::PyGatewayConstruct
#ifdef _MSC_VER
// Disable an OK warning...
#pragma warning( disable : 4275 )
// warning C4275: non dll-interface struct 'IDispatch' used as base for dll-interface class 'PyGatewayBase'
#endif // _MSC_VER
// Helper interface for fetching a Python object from a gateway
extern const GUID IID_IInternalUnwrapPythonObject;
interface IInternalUnwrapPythonObject : public IUnknown
{
public:
STDMETHOD(Unwrap)( PyObject **ppPyObject ) = 0;
};
/////////////////////////////////////////////////////////////////////////////
// PyGatewayBase
//
// Base class for all gateways.
//
class PYCOM_EXPORT PyGatewayBase :
#ifndef NO_PYCOM_IDISPATCHEX
public IDispatchEx, // IDispatch comes along for the ride!
#else
public IDispatch, // No IDispatchEx - must explicitely use IDispatch
#endif
public ISupportErrorInfo,
public IInternalUnwrapPythonObject
{
protected:
PyGatewayBase(PyObject *instance);
virtual ~PyGatewayBase();
// Invoke the Python method (via the policy object)
STDMETHOD(InvokeViaPolicy)(
const char *szMethodName,
PyObject **ppResult = NULL,
const char *szFormat = NULL,
...);
public:
// IUnknown
STDMETHOD_(ULONG,AddRef)(void);
STDMETHOD_(ULONG,Release)(void);
STDMETHOD(QueryInterface)(REFIID iid, void ** obj);
// IDispatch
STDMETHOD(GetTypeInfoCount)(UINT FAR* pctInfo);
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptInfo);
STDMETHOD(GetIDsOfNames)(REFIID refiid, OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid);
STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* params, VARIANT FAR* pVarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr);
// IDispatchEx
#ifndef NO_PYCOM_IDISPATCHEX
STDMETHOD(GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
STDMETHOD(InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
STDMETHOD(DeleteMemberByName)(BSTR bstr, DWORD grfdex);
STDMETHOD(DeleteMemberByDispID)(DISPID id);
STDMETHOD(GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
STDMETHOD(GetMemberName)(DISPID id, BSTR *pbstrName);
STDMETHOD(GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
STDMETHOD(GetNameSpaceParent)(IUnknown **ppunk);
#endif // NO_PYCOM_IDISPATCHEX
// ISupportErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
// IInternalUnwrapPythonObject
STDMETHOD(Unwrap)(PyObject **ppPyObject);
// Basically just PYGATEWAY_MAKE_SUPPORT(PyGatewayBase, IDispatch, IID_IDispatch);
// but with special handling as its the base class.
static HRESULT PyGatewayBase::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *gatewayBase, void **ppResult, REFIID iid)
{
if (ppResult==NULL) return E_INVALIDARG;
PyGatewayBase *obNew = new PyGatewayBase(pPyInstance);
obNew->m_pBaseObject = gatewayBase;
if (gatewayBase) gatewayBase->AddRef();
*ppResult = (IDispatch *)obNew;
return *ppResult ? S_OK : E_OUTOFMEMORY;
}
// Currently this is used only for ISupportErrorInfo,
// so hopefully this will never be called in this base class.
// (however, this is not a rule, so we wont assert or anything!)
virtual IID GetIID(void) { return IID_IUnknown; }
virtual void *ThisAsIID(IID iid);
// End of PYGATEWAY_MAKE_SUPPORT
PyObject * m_pPyObject;
PyGatewayBase *m_pBaseObject;
private:
LONG m_cRef;
};
#ifdef _MSC_VER
#pragma warning(default : 4275 )
#endif // _MSC_VER
// B/W compat hack for gateways.
#define PyCom_HandlePythonFailureToCOM() \
PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, "<unknown>", GetIID())
// F/W compat hack for gateways! Must be careful about updating
// PyGatewayBase vtable, so a slightly older pythoncomXX.dll will work
// with slightly later extensions. So use a #define.
#define MAKE_PYCOM_GATEWAY_FAILURE_CODE(method_name) \
PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, method_name, GetIID())
#endif /* __PYTHONCOMSERVER_H__ */