home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2686 < prev    next >
Encoding:
Text File  |  2006-08-30  |  6.4 KB  |  163 lines

  1. #ifndef __PYTHONCOMSERVER_H__
  2. #define __PYTHONCOMSERVER_H__
  3.  
  4. // PythonCOMServer.h :Server side COM support
  5.  
  6. #include <Python.h>
  7.  
  8. #define DLLAcquireGlobalLock    PyWin_AcquireGlobalLock
  9. #define DLLReleaseGlobalLock    PyWin_ReleaseGlobalLock
  10.  
  11. void PYCOM_EXPORT PyCom_DLLAddRef(void);
  12. void PYCOM_EXPORT PyCom_DLLReleaseRef(void);
  13.  
  14. // Use this macro at the start of all gateway methods.
  15. #define PY_GATEWAY_METHOD CEnterLeavePython _celp
  16.  
  17. class PyGatewayBase;
  18. // Gateway constructors.
  19. // Each gateway must be able to be created from a "gateway constructor".  This
  20. // is simply a function that takes a Python instance as as argument, and returns
  21. // a gateway object of the correct type.  The MAKE_PYGATEWAY_CTOR is a helper that
  22. // will embed such a constructor in the class - however, this is not necessary - 
  23. // _any_ function of the correct signature can be used.
  24.  
  25. typedef HRESULT (* pfnPyGatewayConstructor)(PyObject *PythonInstance, PyGatewayBase *, void **ppResult, REFIID iid);
  26. HRESULT PyCom_MakeRegisteredGatewayObject(REFIID iid, PyObject *instance, PyGatewayBase *base, void **ppv);
  27.  
  28. // A version of the above which support classes being derived from
  29. // other than IUnknown
  30. #define PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, gatewaybaseclass) \
  31.     public: \
  32.         static HRESULT classname::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *unkBase, void **ppResult, REFIID iid) { \
  33.             if (ppResult==NULL) return E_INVALIDARG; \
  34.             classname *newob = new classname(pPyInstance); \
  35.             newob->m_pBaseObject = unkBase; \
  36.             if (unkBase) unkBase->AddRef(); \
  37.             *ppResult = newob->ThisAsIID(iid);  \
  38.             return *ppResult ? S_OK : E_OUTOFMEMORY; } \
  39.     protected: \
  40.         virtual IID GetIID(void) { return theIID; } \
  41.         virtual void *ThisAsIID(IID iid) {if (this==NULL) return NULL;if (iid==theIID) return (IInterface *)this; else return gatewaybaseclass::ThisAsIID(iid);} \
  42.         STDMETHOD_(ULONG,AddRef)(void) {return gatewaybaseclass::AddRef();} \
  43.         STDMETHOD_(ULONG,Release)(void) {return gatewaybaseclass::Release();} \
  44.         STDMETHOD(QueryInterface)(REFIID iid, void ** obj) {return gatewaybaseclass::QueryInterface(iid, obj);};
  45.  
  46. // This is the "old" version to use, or use it if you derive
  47. // directly from PyGatewayBase
  48. #define PYGATEWAY_MAKE_SUPPORT(classname, IInterface, theIID) \
  49.     PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, PyGatewayBase)
  50.  
  51.  
  52. #define GET_PYGATEWAY_CTOR(classname) classname::PyGatewayConstruct
  53.  
  54. #ifdef _MSC_VER
  55. // Disable an OK warning...
  56. #pragma warning( disable : 4275 )
  57. // warning C4275: non dll-interface struct 'IDispatch' used as base for dll-interface class 'PyGatewayBase'
  58. #endif // _MSC_VER
  59.  
  60. // Helper interface for fetching a Python object from a gateway
  61.  
  62. extern const GUID IID_IInternalUnwrapPythonObject;
  63.  
  64. interface IInternalUnwrapPythonObject : public IUnknown
  65. {
  66. public:
  67.     STDMETHOD(Unwrap)( PyObject **ppPyObject ) = 0;
  68. };
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // PyGatewayBase
  72. //
  73. // Base class for all gateways.
  74. //
  75. class PYCOM_EXPORT PyGatewayBase : 
  76. #ifndef NO_PYCOM_IDISPATCHEX
  77.     public IDispatchEx, // IDispatch comes along for the ride!
  78. #else
  79.     public IDispatch,   // No IDispatchEx - must explicitely use IDispatch
  80. #endif
  81.     public ISupportErrorInfo,
  82.     public IInternalUnwrapPythonObject
  83. {
  84. protected:
  85.     PyGatewayBase(PyObject *instance);
  86.     virtual ~PyGatewayBase();
  87.  
  88.     // Invoke the Python method (via the policy object)
  89.     STDMETHOD(InvokeViaPolicy)(
  90.         const char *szMethodName,
  91.         PyObject **ppResult = NULL,
  92.         const char *szFormat = NULL,
  93.         ...);
  94.  
  95. public:
  96.     // IUnknown
  97.     STDMETHOD_(ULONG,AddRef)(void);
  98.     STDMETHOD_(ULONG,Release)(void);
  99.     STDMETHOD(QueryInterface)(REFIID iid, void ** obj);
  100.  
  101.     // IDispatch
  102.     STDMETHOD(GetTypeInfoCount)(UINT FAR* pctInfo);
  103.     STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptInfo);
  104.     STDMETHOD(GetIDsOfNames)(REFIID refiid,    OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid);
  105.     STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* params, VARIANT FAR* pVarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr);
  106.  
  107.     // IDispatchEx
  108. #ifndef NO_PYCOM_IDISPATCHEX
  109.     STDMETHOD(GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
  110.     STDMETHOD(InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
  111.     STDMETHOD(DeleteMemberByName)(BSTR bstr, DWORD grfdex);
  112.     STDMETHOD(DeleteMemberByDispID)(DISPID id);
  113.     STDMETHOD(GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
  114.     STDMETHOD(GetMemberName)(DISPID id, BSTR *pbstrName);
  115.     STDMETHOD(GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
  116.     STDMETHOD(GetNameSpaceParent)(IUnknown **ppunk);
  117. #endif // NO_PYCOM_IDISPATCHEX
  118.     // ISupportErrorInfo
  119.     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  120.  
  121.     // IInternalUnwrapPythonObject
  122.     STDMETHOD(Unwrap)(PyObject **ppPyObject);
  123.  
  124.     // Basically just PYGATEWAY_MAKE_SUPPORT(PyGatewayBase, IDispatch, IID_IDispatch);
  125.     // but with special handling as its the base class.
  126.     static HRESULT PyGatewayBase::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *gatewayBase, void **ppResult, REFIID iid)
  127.     {
  128.         if (ppResult==NULL) return E_INVALIDARG;
  129.         PyGatewayBase *obNew = new PyGatewayBase(pPyInstance);
  130.         obNew->m_pBaseObject = gatewayBase;
  131.         if (gatewayBase) gatewayBase->AddRef();
  132.         *ppResult = (IDispatch *)obNew;
  133.         return *ppResult ? S_OK : E_OUTOFMEMORY;
  134.     }
  135.     // Currently this is used only for ISupportErrorInfo,
  136.     // so hopefully this will never be called in this base class.
  137.     // (however, this is not a rule, so we wont assert or anything!)
  138.     virtual IID GetIID(void) { return IID_IUnknown; }
  139.     virtual void *ThisAsIID(IID iid);
  140.     // End of PYGATEWAY_MAKE_SUPPORT
  141.     PyObject * m_pPyObject;
  142.     PyGatewayBase *m_pBaseObject;
  143. private:
  144.     LONG m_cRef;
  145. };
  146.  
  147. #ifdef _MSC_VER
  148. #pragma warning(default : 4275 )
  149. #endif // _MSC_VER
  150.  
  151. // B/W compat hack for gateways.
  152. #define PyCom_HandlePythonFailureToCOM() \
  153.     PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, "<unknown>", GetIID())
  154.  
  155. // F/W compat hack for gateways!  Must be careful about updating
  156. // PyGatewayBase vtable, so a slightly older pythoncomXX.dll will work
  157. // with slightly later extensions.  So use a #define.
  158. #define MAKE_PYCOM_GATEWAY_FAILURE_CODE(method_name) \
  159.     PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, method_name, GetIID())
  160.  
  161.  
  162. #endif /* __PYTHONCOMSERVER_H__ */
  163.