home *** CD-ROM | disk | FTP | other *** search
- #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__ */
-