Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PythonCOM.h 30KB

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