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__