/ lib / win32com / include / PythonCOM.h
PythonCOM.h
  1  /* PythonCOM.h
  2  
  3   Main header for Python COM support.
  4  
  5   This file is involved mainly with client side COM support for
  6   Python.
  7  
  8   Most COM work put together by Greg Stein and Mark Hammond, with a
  9   few others starting to come out of the closet.
 10  
 11  
 12   --------------------------------------------------------------------
 13   Thread State Rules
 14   ------------------
 15   These rules apply to PythonCOM in general, and not just to
 16   the client side.
 17  
 18   The rules are quite simple, but it is critical they be followed.
 19   In general, errors here will be picked up quite quickly, as Python
 20   will raise a Fatal Error.  However, the Release() issue in particular
 21   may keep a number of problems well hidden.
 22  
 23   Interfaces:
 24   -----------
 25   Before making ANY call out to COM, you MUST release the Python lock.
 26   This is true to ANY call whatsoever, including the COM call in question,
 27   but also any calls to "->Release();"
 28  
 29   This is normally achieved with the calls
 30   PY_INTERFACE_PRECALL and PY_INTERFACE_POSTCALL, which release
 31   and acquire the Python lock.
 32  
 33   Gateways:
 34   ---------
 35   Before doing anything related to Python, gateways MUST acquire the
 36   Python lock, and must release it before returning.
 37  
 38   This is normally achieved with PY_GATEWAY_METHOD at the top of a
 39   gateway method.  This macro resolves to a class, which automatically does
 40   the right thing.
 41  
 42   Release:
 43   --------
 44   As mentioned above for Interfaces, EVERY call to Release() must be done
 45   with the Python lock released.  This is expanded here.
 46  
 47   This is very important, but an error may not be noticed.  The problem will
 48   only be seen when the Release() is on a Python object and the Release() is the
 49   final one for the object.  In this case, the Python object will attempt to
 50   acquire the Python lock before destroying itself, and Python will raise a
 51   fatal error.
 52  
 53   In many many cases, you will not notice this error, but someday, someone will
 54   implement the other side in Python, and suddenly FatalErrors will start
 55   appearing.  Make sure you get this right.
 56  
 57   Eg, this code is correct:
 58     PY_INTERFACE_PRECALL;
 59     pSomeObj->SomeFunction(pSomeOtherObject);
 60     pSomeOtherObject->Release();
 61     PY_INTERFACE_POSTCALL;
 62  
 63   However, this code is WRONG, but will RARELY FAIL.
 64     PY_INTERFACE_PRECALL;
 65     pSomeObj->SomeFunction(pSomeOtherObject);
 66     PY_INTERFACE_POSTCALL;
 67     pSomeOtherObject->Release();
 68  --------------------------------------------------------------------
 69  */
 70  #ifndef __PYTHONCOM_H__
 71  #define __PYTHONCOM_H__
 72  
 73  // #define _DEBUG_LIFETIMES // Trace COM object lifetimes.
 74  
 75  #ifdef FREEZE_PYTHONCOM
 76  /* The pythoncom module is being included in a frozen .EXE/.DLL */
 77  #define PYCOM_EXPORT
 78  #else
 79  #ifdef BUILD_PYTHONCOM
 80  /* We are building pythoncomxx.dll */
 81  #define PYCOM_EXPORT __declspec(dllexport)
 82  #else
 83  /* This module uses pythoncomxx.dll */
 84  #define PYCOM_EXPORT __declspec(dllimport)
 85  #ifndef _DEBUG
 86  #pragma comment(lib, "pythoncom.lib")
 87  #else
 88  #pragma comment(lib, "pythoncom_d.lib")
 89  #endif
 90  #endif
 91  #endif
 92  
 93  #ifdef MS_WINCE
 94  // List of interfaces not supported by CE.
 95  #define NO_PYCOM_IDISPATCHEX
 96  #define NO_PYCOM_IPROVIDECLASSINFO
 97  #define NO_PYCOM_IENUMGUID
 98  #define NO_PYCOM_IENUMCATEGORYINFO
 99  #define NO_PYCOM_ICATINFORMATION
100  #define NO_PYCOM_ICATREGISTER
101  #define NO_PYCOM_ISERVICEPROVIDER
102  #define NO_PYCOM_IPROPERTYSTORAGE
103  #define NO_PYCOM_IPROPERTYSETSTORAGE
104  #define NO_PYCOM_ENUMSTATPROPSTG
105  
106  #include "ocidl.h"
107  #include "oleauto.h"
108  
109  #endif  // MS_WINCE
110  
111  #ifdef __MINGW32__
112  // Special Mingw32 considerations.
113  #define NO_PYCOM_ENUMSTATPROPSTG
114  #define __try try
115  #define __except catch
116  #include <olectl.h>
117  
118  #endif  // __MINGW32__
119  
120  #include <PyWinTypes.h>  // Standard Win32 Types
121  
122  #ifndef NO_PYCOM_IDISPATCHEX
123  #include <dispex.h>  // New header for IDispatchEx interface.
124  #endif               // NO_PYCOM_IDISPATCHEX
125  
126  #if defined(MAINWIN)
127  // Mainwin seems to have 1/2 the VT_RECORD infrastructure in place
128  #if !defined(VT_RECORD)
129  #define VT_RECORD 36
130  #define V_RECORDINFO(X) ((X)->brecVal.pRecInfo)
131  #define V_RECORD(X) ((X)->brecVal.pvRecord)
132  #else
133  #pragma message(                                       \
134      "MAINWIN appears to have grown correct VT_RECORD " \
135      "support. Please update PythonCOM.h accordingly")
136  #endif  // VT_RECORD
137  #endif  // MAINWIN
138  
139  class PyIUnknown;
140  // To make life interesting/complicated, I use C++ classes for
141  // all Python objects.  The main advantage is that I can derive
142  // a PyIDispatch object from a PyIUnknown, etc.  This provides a
143  // clean C++ interface, and "automatically" provides all base
144  // Python methods to "derived" Python types.
145  //
146  // Main disadvantage is that any extension DLLs will need to include
147  // these headers, and link with this .lib
148  //
149  // Base class for (most of) the type objects.
150  
151  class PYCOM_EXPORT PyComTypeObject : public PyTypeObject {
152     public:
153      PyComTypeObject(const char *name, PyComTypeObject *pBaseType, Py_ssize_t typeSize, struct PyMethodDef *methodList,
154                      PyIUnknown *(*thector)(IUnknown *));
155      ~PyComTypeObject();
156  
157      // is the given object an interface type object? (e.g. PyIUnknown)
158      static BOOL is_interface_type(PyObject *ob);
159  
160     public:
161      PyIUnknown *(*ctor)(IUnknown *);
162  };
163  
164  // A type used for interfaces that can automatically provide enumerators
165  // (ie, they themselves aren't enumerable, but do have a suitable default
166  // method that returns a PyIEnum object
167  class PYCOM_EXPORT PyComEnumProviderTypeObject : public PyComTypeObject {
168     public:
169      PyComEnumProviderTypeObject(const char *name, PyComTypeObject *pBaseType, Py_ssize_t typeSize,
170                                  struct PyMethodDef *methodList, PyIUnknown *(*thector)(IUnknown *),
171                                  const char *enum_method_name);
172      static PyObject *iter(PyObject *self);
173      const char *enum_method_name;
174  };
175  
176  // A type used for PyIEnum interfaces
177  class PYCOM_EXPORT PyComEnumTypeObject : public PyComTypeObject {
178     public:
179      static PyObject *iter(PyObject *self);
180      static PyObject *iternext(PyObject *self);
181      PyComEnumTypeObject(const char *name, PyComTypeObject *pBaseType, Py_ssize_t typeSize, struct PyMethodDef *methodList,
182                          PyIUnknown *(*thector)(IUnknown *));
183  };
184  
185  // Very very base class - not COM specific - Should exist in the
186  // Python core somewhere, IMO.
187  class PYCOM_EXPORT PyIBase : public PyObject {
188     public:
189      // virtuals for Python support
190      virtual PyObject *getattr(char *name);
191      virtual int setattr(char *name, PyObject *v);
192      virtual PyObject *repr();
193      virtual int compare(PyObject *other)
194      {
195          if (this == other)
196              return 0;
197          if (this < other)
198              return -1;
199          return 1;
200      }
201      // These iter are a little special, in that returning NULL means
202      // use the implementation in the type
203      virtual PyObject *iter() { return NULL; }
204      virtual PyObject *iternext() { return NULL; }
205  
206     protected:
207      PyIBase();
208      virtual ~PyIBase();
209  
210     public:
211      static BOOL is_object(PyObject *, PyComTypeObject *which);
212      BOOL is_object(PyComTypeObject *which);
213      static void dealloc(PyObject *ob);
214      static PyObject *repr(PyObject *ob);
215      static PyObject *getattro(PyObject *self, PyObject *name);
216      static int setattro(PyObject *op, PyObject *obname, PyObject *v);
217      static int cmp(PyObject *ob1, PyObject *ob2);
218      static PyObject *richcmp(PyObject *ob1, PyObject *ob2, int op);
219  };
220  
221  /* Special Type objects */
222  extern PYCOM_EXPORT PyTypeObject PyOleEmptyType;        // equivalent to VT_EMPTY
223  extern PYCOM_EXPORT PyTypeObject PyOleMissingType;      // special Python handling.
224  extern PYCOM_EXPORT PyTypeObject PyOleArgNotFoundType;  // special VT_ERROR value
225  extern PYCOM_EXPORT PyTypeObject PyOleNothingType;      // special VT_ERROR value
226  
227  // ALL of these set an appropriate Python error on bad return.
228  
229  // Given a Python object that is a registered COM type, return a given
230  // interface pointer on its underlying object, with a new reference added.
231  PYCOM_EXPORT BOOL PyCom_InterfaceFromPyObject(PyObject *ob, REFIID iid, LPVOID *ppv, BOOL bNoneOK = TRUE);
232  
233  // As above, but allows instance with "_oleobj_" attribute.
234  PYCOM_EXPORT BOOL PyCom_InterfaceFromPyInstanceOrObject(PyObject *ob, REFIID iid, LPVOID *ppv, BOOL bNoneOK = TRUE);
235  
236  // Release an arbitary COM pointer.
237  // NOTE: the PRECALL/POSTCALL stuff is probably not strictly necessary
238  // since the PyGILSTATE stuff has been in place (and even then, it only
239  // mattered when it was the last Release() on a Python implemented object)
240  #define PYCOM_RELEASE(pUnk)        \
241      {                              \
242          if (pUnk) {                \
243              PY_INTERFACE_PRECALL;  \
244              (pUnk)->Release();     \
245              PY_INTERFACE_POSTCALL; \
246          }                          \
247      }
248  
249  // Given an IUnknown and an Interface ID, create and return an object
250  // of the appropriate type. eg IID_Unknown->PyIUnknown,
251  // IID_IDispatch->PyIDispatch, etc.
252  // Uses a map that external extension DLLs can populate with their IID/type.
253  // Under the principal of least surprise, this will return Py_None is punk is NULL.
254  //  Otherwise, a valid PyI*, but with NULL m_obj (and therefore totally useless)
255  //  object would be created.
256  // BOOL bAddRef indicates if a COM reference count should be added to the IUnknown.
257  //  This depends purely on the context in which it is called.  If the IUnknown is obtained
258  //  from a function that creates a new ref (eg, CoCreateInstance()) then you should use
259  //  FALSE.  If you receive the pointer as (eg) a param to a gateway function, then
260  //  you normally need to pass TRUE, as this is truly a new reference.
261  //  *** ALWAYS take the time to get this right. ***
262  PYCOM_EXPORT PyObject *PyCom_PyObjectFromIUnknown(IUnknown *punk, REFIID riid, BOOL bAddRef = FALSE);
263  
264  // VARIANT <-> PyObject conversion utilities.
265  PYCOM_EXPORT BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var);
266  PYCOM_EXPORT PyObject *PyCom_PyObjectFromVariant(const VARIANT *var);
267  
268  // PROPVARIANT
269  PYCOM_EXPORT PyObject *PyObject_FromPROPVARIANT(PROPVARIANT *pVar);
270  PYCOM_EXPORT PyObject *PyObject_FromPROPVARIANTs(PROPVARIANT *pVars, ULONG cVars);
271  PYCOM_EXPORT BOOL PyObject_AsPROPVARIANT(PyObject *ob, PROPVARIANT *pVar);
272  
273  // Other conversion helpers...
274  PYCOM_EXPORT PyObject *PyCom_PyObjectFromSTATSTG(STATSTG *pStat);
275  PYCOM_EXPORT BOOL PyCom_PyObjectAsSTATSTG(PyObject *ob, STATSTG *pStat, DWORD flags = 0);
276  PYCOM_EXPORT BOOL PyCom_SAFEARRAYFromPyObject(PyObject *obj, SAFEARRAY **ppSA, VARENUM vt = VT_VARIANT);
277  PYCOM_EXPORT PyObject *PyCom_PyObjectFromSAFEARRAY(SAFEARRAY *psa, VARENUM vt = VT_VARIANT);
278  #ifndef NO_PYCOM_STGOPTIONS
279  PYCOM_EXPORT BOOL PyCom_PyObjectAsSTGOPTIONS(PyObject *obstgoptions, STGOPTIONS **ppstgoptions, TmpWCHAR *tmpw_shelve);
280  #endif
281  PYCOM_EXPORT PyObject *PyCom_PyObjectFromSTATPROPSETSTG(STATPROPSETSTG *pStat);
282  PYCOM_EXPORT BOOL PyCom_PyObjectAsSTATPROPSETSTG(PyObject *, STATPROPSETSTG *);
283  
284  // Currency support.
285  PYCOM_EXPORT PyObject *PyObject_FromCurrency(CURRENCY &cy);
286  PYCOM_EXPORT BOOL PyObject_AsCurrency(PyObject *ob, CURRENCY *pcy);
287  
288  // OLEMENUGROUPWIDTHS are used by axcontrol, shell, etc
289  PYCOM_EXPORT BOOL PyObject_AsOLEMENUGROUPWIDTHS(PyObject *oblpMenuWidths, OLEMENUGROUPWIDTHS *pWidths);
290  PYCOM_EXPORT PyObject *PyObject_FromOLEMENUGROUPWIDTHS(const OLEMENUGROUPWIDTHS *pWidths);
291  
292  /* Functions for Initializing COM, and also letting the core know about it!
293   */
294  PYCOM_EXPORT HRESULT PyCom_CoInitializeEx(LPVOID reserved, DWORD dwInit);
295  PYCOM_EXPORT HRESULT PyCom_CoInitialize(LPVOID reserved);
296  PYCOM_EXPORT void PyCom_CoUninitialize();
297  
298  ///////////////////////////////////////////////////////////////////
299  // Error related functions
300  
301  // Client related functions - generally called by interfaces before
302  // they return NULL back to Python to indicate the error.
303  // All these functions return NULL so interfaces can generally
304  // just "return PyCom_BuildPyException(hr, punk, IID_IWhatever)"
305  
306  // Uses the HRESULT, and IErrorInfo interfaces if available to
307  // create and set a pythoncom.com_error.
308  PYCOM_EXPORT PyObject *PyCom_BuildPyException(HRESULT hr, IUnknown *pUnk = NULL, REFIID iid = IID_NULL);
309  
310  // Uses the HRESULT and an EXCEPINFO structure to create and
311  // set a pythoncom.com_error.
312  PYCOM_EXPORT PyObject *PyCom_BuildPyExceptionFromEXCEPINFO(HRESULT hr, EXCEPINFO *pexcepInfo, UINT nArgErr = (UINT)-1);
313  
314  // Sets a pythoncom.internal_error - no one should ever see these!
315  PYCOM_EXPORT PyObject *PyCom_BuildInternalPyException(char *msg);
316  
317  // Log an error to a Python logger object if one can be found, or
318  // to stderr if no log available.
319  // If logProvider is not NULL, we will call a "_GetLogger_()" method on it.
320  // If logProvider is NULL, we attempt to fetch "win32com.logger".
321  // If they do not exist, return None, or raise an error fetching them
322  // (or even writing to them once fetched), the message still goes to stderr.
323  // NOTE: By default, win32com does *not* provide a logger, so default is that
324  // all errors are written to stdout.
325  // This will *not* write a record if a COM Server error is current.
326  PYCOM_EXPORT void PyCom_LoggerNonServerException(PyObject *logProvider, const WCHAR *fmt, ...);
327  
328  // Write an error record, including exception.  This will write an error
329  // record even if a COM server error is current.
330  PYCOM_EXPORT void PyCom_LoggerException(PyObject *logProvider, const WCHAR *fmt, ...);
331  
332  // Write a warning record - in general this does *not* mean a call failed, but
333  // still is something in the programmers control that they should change.
334  // XXX - if an exception is pending when this is called, the traceback will
335  // also be written.  This is undesirable and will be changed should this
336  // start being a problem.
337  PYCOM_EXPORT void PyCom_LoggerWarning(PyObject *logProvider, const WCHAR *fmt, ...);
338  
339  // Server related error functions
340  // These are supplied so that any Python errors we detect can be
341  // converted into COM error information.  The HRESULT returned should
342  // be returned by the COM function, and these functions also set the
343  // IErrorInfo interfaces, so the caller can extract more detailed
344  // information about the Python exception.
345  
346  // Set a COM exception, logging the exception if not an explicitly raised 'server' exception
347  PYCOM_EXPORT HRESULT PyCom_SetAndLogCOMErrorFromPyException(const char *methodName, REFIID riid /* = IID_NULL */);
348  PYCOM_EXPORT HRESULT PyCom_SetAndLogCOMErrorFromPyExceptionEx(PyObject *provider, const char *methodName,
349                                                                REFIID riid /* = IID_NULL */);
350  
351  // Used in gateways to SetErrorInfo() with a simple HRESULT, then return it.
352  // The description is generally only useful for debugging purposes,
353  // and if you are debugging via a server that supports IErrorInfo (like Python :-)
354  // NOTE: this function is usuable from outside the Python context
355  PYCOM_EXPORT HRESULT PyCom_SetCOMErrorFromSimple(HRESULT hr, REFIID riid = IID_NULL, const WCHAR *description = NULL);
356  
357  // Used in gateways to check if an IEnum*'s Next() or Clone() method worked.
358  PYCOM_EXPORT HRESULT PyCom_CheckIEnumNextResult(HRESULT hr, REFIID riid);
359  
360  // Used in gateways when an enumerator expected a sequence but didn't get it.
361  PYCOM_EXPORT HRESULT PyCom_HandleIEnumNoSequence(REFIID riid);
362  
363  // Used in gateways to SetErrorInfo() the current Python exception, and
364  // (assuming not a server error explicitly raised) also logs an error
365  // to stdout/win32com.logger.
366  // NOTE: this function assumes GIL held
367  PYCOM_EXPORT HRESULT PyCom_SetCOMErrorFromPyException(REFIID riid = IID_NULL);
368  
369  // A couple of EXCEPINFO helpers - could be private to IDispatch
370  // if it wasnt for the AXScript support (and ITypeInfo if we get around to that :-)
371  // These functions do not set any error states to either Python or
372  // COM - they simply convert to/from PyObjects and EXCEPINFOs
373  
374  // Use the current Python exception to fill an EXCEPINFO structure.
375  PYCOM_EXPORT void PyCom_ExcepInfoFromPyException(EXCEPINFO *pExcepInfo);
376  
377  // Fill in an EXCEPINFO structure from a Python instance or tuple object.
378  // (ie, similar to the above, except the Python exception object is specified,
379  // rather than using the "current"
380  PYCOM_EXPORT BOOL PyCom_ExcepInfoFromPyObject(PyObject *obExcepInfo, EXCEPINFO *pexcepInfo, HRESULT *phresult = NULL);
381  
382  // Create a Python object holding the exception information.  The exception
383  // information is *not* freed by this function.  Python exceptions are
384  // raised and NULL is returned if an error occurs.
385  PYCOM_EXPORT PyObject *PyCom_PyObjectFromExcepInfo(const EXCEPINFO *pexcepInfo);
386  
387  ///////////////////////////////////////////////////////////////////
388  //
389  // External C++ helpers - these helpers are for other DLLs which
390  // may need similar functionality, but dont want to duplicate all
391  
392  // This helper is for an application that has an IDispatch, and COM arguments
393  // and wants to call a Python function.  It is assumed the caller can map the IDispatch
394  // to a Python object, so the Python handler is passed.
395  // Args:
396  //   handler : A Python callable object.
397  //   dispparms : the COM arguments.
398  //   pVarResult : The variant for the return value of the Python call.
399  //   pexcepinfo : Exception info the helper may fill out.
400  //   puArgErr : Argument error the helper may fill out on exception
401  //   addnArgs : Any additional arguments to the Python function.  May be NULL.
402  // If addnArgs is NULL, then it is assumed the Python call should be native -
403  // ie, the COM args are packed as normal Python args to the call.
404  // If addnArgs is NOT NULL, it is assumed the Python function itself is
405  // a helper.  This Python function will be called with 2 arguments - both
406  // tuples - first one is the COM args, second is the addn args.
407  PYCOM_EXPORT BOOL PyCom_MakeOlePythonCall(PyObject *handler, DISPPARAMS FAR *params, VARIANT FAR *pVarResult,
408                                            EXCEPINFO FAR *pexcepinfo, UINT FAR *puArgErr, PyObject *addnlArgs);
409  
410  /////////////////////////////////////////////////////////////////////////////
411  // Various special purpose singletons
412  class PYCOM_EXPORT PyOleEmpty : public PyObject {
413     public:
414      PyOleEmpty();
415  };
416  
417  class PYCOM_EXPORT PyOleMissing : public PyObject {
418     public:
419      PyOleMissing();
420  };
421  
422  class PYCOM_EXPORT PyOleArgNotFound : public PyObject {
423     public:
424      PyOleArgNotFound();
425  };
426  
427  class PYCOM_EXPORT PyOleNothing : public PyObject {
428     public:
429      PyOleNothing();
430  };
431  
432  // We need to dynamically create C++ Python objects
433  // These helpers allow each type object to create it.
434  #define MAKE_PYCOM_CTOR(classname) \
435      static PyIUnknown *classname::PyObConstruct(IUnknown *pInitObj) { return new classname(pInitObj); }
436  #define MAKE_PYCOM_CTOR_ERRORINFO(classname, iid)                                                       \
437      static PyIUnknown *classname::PyObConstruct(IUnknown *pInitObj) { return new classname(pInitObj); } \
438      static PyObject *SetPythonCOMError(PyObject *self, HRESULT hr)                                      \
439      {                                                                                                   \
440          return PyCom_BuildPyException(hr, GetI(self), iid);                                             \
441      }
442  #define GET_PYCOM_CTOR(classname) classname::PyObConstruct
443  
444  // Macros that interfaces should use.  PY_INTERFACE_METHOD at the top of the method
445  // The other 2 wrap directly around the underlying method call.
446  #define PY_INTERFACE_METHOD
447  // Identical to Py_BEGIN_ALLOW_THREADS except no { !!!
448  #define PY_INTERFACE_PRECALL PyThreadState *_save = PyEval_SaveThread();
449  #define PY_INTERFACE_POSTCALL PyEval_RestoreThread(_save);
450  
451  /////////////////////////////////////////////////////////////////////////////
452  // class PyIUnknown
453  class PYCOM_EXPORT PyIUnknown : public PyIBase {
454     public:
455      MAKE_PYCOM_CTOR(PyIUnknown);
456      virtual PyObject *repr();
457      virtual int compare(PyObject *other);
458  
459      static IUnknown *GetI(PyObject *self);
460      IUnknown *m_obj;
461      static char *szErrMsgObjectReleased;
462      static void SafeRelease(PyIUnknown *ob);
463      static PyComTypeObject type;
464  
465      // The Python methods
466      static PyObject *QueryInterface(PyObject *self, PyObject *args);
467      static PyObject *SafeRelease(PyObject *self, PyObject *args);
468  
469     protected:
470      PyIUnknown(IUnknown *punk);
471      ~PyIUnknown();
472  };
473  
474  /////////////////////////////////////////////////////////////////////////////
475  // class PyIDispatch
476  
477  class PYCOM_EXPORT PyIDispatch : public PyIUnknown {
478     public:
479      MAKE_PYCOM_CTOR(PyIDispatch);
480      static IDispatch *GetI(PyObject *self);
481      static PyComTypeObject type;
482  
483      // The Python methods
484      static PyObject *Invoke(PyObject *self, PyObject *args);
485      static PyObject *InvokeTypes(PyObject *self, PyObject *args);
486      static PyObject *GetIDsOfNames(PyObject *self, PyObject *args);
487      static PyObject *GetTypeInfo(PyObject *self, PyObject *args);
488      static PyObject *GetTypeInfoCount(PyObject *self, PyObject *args);
489  
490     protected:
491      PyIDispatch(IUnknown *pdisp);
492      ~PyIDispatch();
493  };
494  
495  #ifndef NO_PYCOM_IDISPATCHEX
496  /////////////////////////////////////////////////////////////////////////////
497  // class PyIDispatchEx
498  
499  class PYCOM_EXPORT PyIDispatchEx : public PyIDispatch {
500     public:
501      MAKE_PYCOM_CTOR_ERRORINFO(PyIDispatchEx, IID_IDispatchEx);
502      static IDispatchEx *GetI(PyObject *self);
503      static PyComTypeObject type;
504  
505      // The Python methods
506      static PyObject *GetDispID(PyObject *self, PyObject *args);
507      static PyObject *InvokeEx(PyObject *self, PyObject *args);
508      static PyObject *DeleteMemberByName(PyObject *self, PyObject *args);
509      static PyObject *DeleteMemberByDispID(PyObject *self, PyObject *args);
510      static PyObject *GetMemberProperties(PyObject *self, PyObject *args);
511      static PyObject *GetMemberName(PyObject *self, PyObject *args);
512      static PyObject *GetNextDispID(PyObject *self, PyObject *args);
513  
514     protected:
515      PyIDispatchEx(IUnknown *pdisp);
516      ~PyIDispatchEx();
517  };
518  #endif  // NO_PYCOM_IDISPATCHEX
519  
520  /////////////////////////////////////////////////////////////////////////////
521  // class PyIClassFactory
522  
523  class PYCOM_EXPORT PyIClassFactory : public PyIUnknown {
524     public:
525      MAKE_PYCOM_CTOR(PyIClassFactory);
526      static IClassFactory *GetI(PyObject *self);
527      static PyComTypeObject type;
528  
529      // The Python methods
530      static PyObject *CreateInstance(PyObject *self, PyObject *args);
531      static PyObject *LockServer(PyObject *self, PyObject *args);
532  
533     protected:
534      PyIClassFactory(IUnknown *pdisp);
535      ~PyIClassFactory();
536  };
537  
538  #ifndef NO_PYCOM_IPROVIDECLASSINFO
539  
540  /////////////////////////////////////////////////////////////////////////////
541  // class PyIProvideTypeInfo
542  
543  class PYCOM_EXPORT PyIProvideClassInfo : public PyIUnknown {
544     public:
545      MAKE_PYCOM_CTOR(PyIProvideClassInfo);
546      static IProvideClassInfo *GetI(PyObject *self);
547      static PyComTypeObject type;
548  
549      // The Python methods
550      static PyObject *GetClassInfo(PyObject *self, PyObject *args);
551  
552     protected:
553      PyIProvideClassInfo(IUnknown *pdisp);
554      ~PyIProvideClassInfo();
555  };
556  
557  class PYCOM_EXPORT PyIProvideClassInfo2 : public PyIProvideClassInfo {
558     public:
559      MAKE_PYCOM_CTOR(PyIProvideClassInfo2);
560      static IProvideClassInfo2 *GetI(PyObject *self);
561      static PyComTypeObject type;
562  
563      // The Python methods
564      static PyObject *GetGUID(PyObject *self, PyObject *args);
565  
566     protected:
567      PyIProvideClassInfo2(IUnknown *pdisp);
568      ~PyIProvideClassInfo2();
569  };
570  #endif  // NO_PYCOM_IPROVIDECLASSINFO
571  
572  /////////////////////////////////////////////////////////////////////////////
573  // class PyITypeInfo
574  class PYCOM_EXPORT PyITypeInfo : public PyIUnknown {
575     public:
576      MAKE_PYCOM_CTOR(PyITypeInfo);
577      static PyComTypeObject type;
578      static ITypeInfo *GetI(PyObject *self);
579  
580      PyObject *GetContainingTypeLib();
581      PyObject *GetDocumentation(MEMBERID);
582      PyObject *GetRefTypeInfo(HREFTYPE href);
583      PyObject *GetRefTypeOfImplType(int index);
584      PyObject *GetFuncDesc(int pos);
585      PyObject *GetIDsOfNames(OLECHAR FAR *FAR *, int);
586      PyObject *GetNames(MEMBERID);
587      PyObject *GetTypeAttr();
588      PyObject *GetVarDesc(int pos);
589      PyObject *GetImplTypeFlags(int index);
590      PyObject *GetTypeComp();
591  
592     protected:
593      PyITypeInfo(IUnknown *);
594      ~PyITypeInfo();
595  };
596  
597  /////////////////////////////////////////////////////////////////////////////
598  // class PyITypeComp
599  class PYCOM_EXPORT PyITypeComp : public PyIUnknown {
600     public:
601      MAKE_PYCOM_CTOR(PyITypeComp);
602      static PyComTypeObject type;
603      static ITypeComp *GetI(PyObject *self);
604  
605      PyObject *Bind(OLECHAR *szName, unsigned short wflags);
606      PyObject *BindType(OLECHAR *szName);
607  
608     protected:
609      PyITypeComp(IUnknown *);
610      ~PyITypeComp();
611  };
612  
613  /////////////////////////////////////////////////////////////////////////////
614  // class CPyTypeLib
615  
616  class PYCOM_EXPORT PyITypeLib : public PyIUnknown {
617     public:
618      MAKE_PYCOM_CTOR(PyITypeLib);
619      static PyComTypeObject type;
620      static ITypeLib *GetI(PyObject *self);
621  
622      PyObject *GetLibAttr();
623      PyObject *GetDocumentation(int pos);
624      PyObject *GetTypeInfo(int pos);
625      PyObject *GetTypeInfoCount();
626      PyObject *GetTypeInfoOfGuid(REFGUID guid);
627      PyObject *GetTypeInfoType(int pos);
628      PyObject *GetTypeComp();
629  
630     protected:
631      PyITypeLib(IUnknown *);
632      ~PyITypeLib();
633  };
634  
635  /////////////////////////////////////////////////////////////////////////////
636  // class PyIConnectionPoint
637  
638  class PYCOM_EXPORT PyIConnectionPoint : public PyIUnknown {
639     public:
640      MAKE_PYCOM_CTOR_ERRORINFO(PyIConnectionPoint, IID_IConnectionPoint);
641      static PyComTypeObject type;
642      static IConnectionPoint *GetI(PyObject *self);
643  
644      static PyObject *GetConnectionInterface(PyObject *self, PyObject *args);
645      static PyObject *GetConnectionPointContainer(PyObject *self, PyObject *args);
646      static PyObject *Advise(PyObject *self, PyObject *args);
647      static PyObject *Unadvise(PyObject *self, PyObject *args);
648      static PyObject *EnumConnections(PyObject *self, PyObject *args);
649  
650     protected:
651      PyIConnectionPoint(IUnknown *);
652      ~PyIConnectionPoint();
653  };
654  
655  class PYCOM_EXPORT PyIConnectionPointContainer : public PyIUnknown {
656     public:
657      MAKE_PYCOM_CTOR_ERRORINFO(PyIConnectionPointContainer, IID_IConnectionPointContainer);
658      static PyComTypeObject type;
659      static IConnectionPointContainer *GetI(PyObject *self);
660  
661      static PyObject *EnumConnectionPoints(PyObject *self, PyObject *args);
662      static PyObject *FindConnectionPoint(PyObject *self, PyObject *args);
663  
664     protected:
665      PyIConnectionPointContainer(IUnknown *);
666      ~PyIConnectionPointContainer();
667  };
668  
669  /////////////////////////////////////////////////////////////////////////////
670  // class PythonOleArgHelper
671  //
672  // A PythonOleArgHelper is used primarily to help out Python helpers
673  // which need to convert from a Python object when the specific OLE
674  // type is known - eg, when a TypeInfo is available.
675  //
676  // The type of conversion determines who owns what buffers etc.  I wish BYREF didnt exist :-)
677  typedef enum {
678      // We dont know what sort of conversion it is yet.
679      POAH_CONVERT_UNKNOWN,
680      // A PyObject is given, we convert to a VARIANT, make the COM call, then BYREFs back to a PyObject
681      // ie, this is typically a "normal" COM call, where Python initiates the call
682      POAH_CONVERT_FROM_PYOBJECT,
683      // A VARIANT is given, we convert to a PyObject, make the Python call, then BYREFs back to a VARIANT.
684      // ie, this is typically handling a COM event, where COM itself initiates the call.
685      POAH_CONVERT_FROM_VARIANT,
686  } POAH_CONVERT_DIRECTION;
687  
688  class PYCOM_EXPORT PythonOleArgHelper {
689     public:
690      PythonOleArgHelper();
691      ~PythonOleArgHelper();
692      BOOL ParseTypeInformation(PyObject *reqdObjectTuple);
693  
694      // Using this call with reqdObject != NULL will check the existing
695      // VT_ of the variant.  If not VT_EMPTY, then the result will be coerced to
696      // that type.  This contrasts with PyCom_PyObjectToVariant which just
697      // uses the Python type to determine the variant type.
698      BOOL MakeObjToVariant(PyObject *obj, VARIANT *var, PyObject *reqdObjectTuple = NULL);
699      PyObject *MakeVariantToObj(VARIANT *var);
700  
701      VARTYPE m_reqdType;
702      BOOL m_bParsedTypeInfo;
703      BOOL m_bIsOut;
704      POAH_CONVERT_DIRECTION m_convertDirection;
705      PyObject *m_pyVariant;  // if non-null, a win32com.client.VARIANT
706      union {
707          void *m_pValueHolder;
708          short m_sBuf;
709          long m_lBuf;
710          LONGLONG m_llBuf;
711          VARIANT_BOOL m_boolBuf;
712          double m_dBuf;
713          float m_fBuf;
714          IDispatch *m_dispBuf;
715          IUnknown *m_unkBuf;
716          SAFEARRAY *m_arrayBuf;
717          VARIANT *m_varBuf;
718          DATE m_dateBuf;
719          CY m_cyBuf;
720      };
721  };
722  
723  /////////////////////////////////////////////////////////////////////////////
724  // global functions and variables
725  PYCOM_EXPORT BOOL MakePythonArgumentTuples(PyObject **pArgs, PythonOleArgHelper **ppHelpers, PyObject **pNamedArgs,
726                                             PythonOleArgHelper **ppNamedHelpers, DISPPARAMS FAR *params);
727  
728  // Convert a Python object to a BSTR - allow embedded NULLs, None, etc.
729  PYCOM_EXPORT BOOL PyCom_BstrFromPyObject(PyObject *stringObject, BSTR *pResult, BOOL bNoneOK = FALSE);
730  
731  // MakeBstrToObj - convert a BSTR into a Python string.
732  //
733  // ONLY USE THIS FOR TRUE BSTR's - Use the fn below for OLECHAR *'s.
734  // NOTE - does not use standard macros, so NULLs get through!
735  PYCOM_EXPORT PyObject *MakeBstrToObj(const BSTR bstr);
736  
737  // Size info is available (eg, a fn returns a string and also fills in a size variable)
738  PYCOM_EXPORT PyObject *MakeOLECHARToObj(const OLECHAR *str, int numChars);
739  
740  // No size info avail.
741  PYCOM_EXPORT PyObject *MakeOLECHARToObj(const OLECHAR *str);
742  
743  PYCOM_EXPORT void PyCom_LogF(const WCHAR *fmt, ...);
744  
745  // Generic conversion from python sequence to VT_VECTOR array
746  // Resulting array must be freed with CoTaskMemFree
747  template <typename arraytype>
748  BOOL SeqToVector(PyObject *ob, arraytype **pA, ULONG *pcount, BOOL (*converter)(PyObject *, arraytype *))
749  {
750      TmpPyObject seq = PyWinSequence_Tuple(ob, pcount);
751      if (seq == NULL)
752          return FALSE;
753      *pA = (arraytype *)CoTaskMemAlloc(*pcount * sizeof(arraytype));
754      if (*pA == NULL) {
755          PyErr_NoMemory();
756          return FALSE;
757      }
758      for (ULONG i = 0; i < *pcount; i++) {
759          PyObject *item = PyTuple_GET_ITEM((PyObject *)seq, i);
760          if (!(*converter)(item, &(*pA)[i]))
761              return FALSE;
762      }
763      return TRUE;
764  }
765  
766  #endif  // __PYTHONCOM_H__