Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
760
venv/Lib/site-packages/win32com/include/PythonCOM.h
Normal file
760
venv/Lib/site-packages/win32com/include/PythonCOM.h
Normal file
|
@ -0,0 +1,760 @@
|
|||
/* PythonCOM.h
|
||||
|
||||
Main header for Python COM support.
|
||||
|
||||
This file is involved mainly with client side COM support for
|
||||
Python.
|
||||
|
||||
Most COM work put together by Greg Stein and Mark Hammond, with a
|
||||
few others starting to come out of the closet.
|
||||
|
||||
|
||||
--------------------------------------------------------------------
|
||||
Thread State Rules
|
||||
------------------
|
||||
These rules apply to PythonCOM in general, and not just to
|
||||
the client side.
|
||||
|
||||
The rules are quite simple, but it is critical they be followed.
|
||||
In general, errors here will be picked up quite quickly, as Python
|
||||
will raise a Fatal Error. However, the Release() issue in particular
|
||||
may keep a number of problems well hidden.
|
||||
|
||||
Interfaces:
|
||||
-----------
|
||||
Before making ANY call out to COM, you MUST release the Python lock.
|
||||
This is true to ANY call whatsoever, including the COM call in question,
|
||||
but also any calls to "->Release();"
|
||||
|
||||
This is normally achieved with the calls
|
||||
PY_INTERFACE_PRECALL and PY_INTERFACE_POSTCALL, which release
|
||||
and acquire the Python lock.
|
||||
|
||||
Gateways:
|
||||
---------
|
||||
Before doing anything related to Python, gateways MUST acquire the
|
||||
Python lock, and must release it before returning.
|
||||
|
||||
This is normally achieved with PY_GATEWAY_METHOD at the top of a
|
||||
gateway method. This macro resolves to a class, which automatically does
|
||||
the right thing.
|
||||
|
||||
Release:
|
||||
--------
|
||||
As mentioned above for Interfaces, EVERY call to Release() must be done
|
||||
with the Python lock released. This is expanded here.
|
||||
|
||||
This is very important, but an error may not be noticed. The problem will
|
||||
only be seen when the Release() is on a Python object and the Release() is the
|
||||
final one for the object. In this case, the Python object will attempt to
|
||||
acquire the Python lock before destroying itself, and Python will raise a
|
||||
fatal error.
|
||||
|
||||
In many many cases, you will not notice this error, but someday, someone will
|
||||
implement the other side in Python, and suddenly FatalErrors will start
|
||||
appearing. Make sure you get this right.
|
||||
|
||||
Eg, this code is correct:
|
||||
PY_INTERFACE_PRECALL;
|
||||
pSomeObj->SomeFunction(pSomeOtherObject);
|
||||
pSomeOtherObject->Release();
|
||||
PY_INTERFACE_POSTCALL;
|
||||
|
||||
However, this code is WRONG, but will RARELY FAIL.
|
||||
PY_INTERFACE_PRECALL;
|
||||
pSomeObj->SomeFunction(pSomeOtherObject);
|
||||
PY_INTERFACE_POSTCALL;
|
||||
pSomeOtherObject->Release();
|
||||
--------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef __PYTHONCOM_H__
|
||||
#define __PYTHONCOM_H__
|
||||
|
||||
// #define _DEBUG_LIFETIMES // Trace COM object lifetimes.
|
||||
|
||||
#ifdef FREEZE_PYTHONCOM
|
||||
/* The pythoncom module is being included in a frozen .EXE/.DLL */
|
||||
#define PYCOM_EXPORT
|
||||
#else
|
||||
#ifdef BUILD_PYTHONCOM
|
||||
/* We are building pythoncomxx.dll */
|
||||
#define PYCOM_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
/* This module uses pythoncomxx.dll */
|
||||
#define PYCOM_EXPORT __declspec(dllimport)
|
||||
#ifndef _DEBUG
|
||||
#pragma comment(lib, "pythoncom.lib")
|
||||
#else
|
||||
#pragma comment(lib, "pythoncom_d.lib")
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINCE
|
||||
// List of interfaces not supported by CE.
|
||||
#define NO_PYCOM_IDISPATCHEX
|
||||
#define NO_PYCOM_IPROVIDECLASSINFO
|
||||
#define NO_PYCOM_IENUMGUID
|
||||
#define NO_PYCOM_IENUMCATEGORYINFO
|
||||
#define NO_PYCOM_ICATINFORMATION
|
||||
#define NO_PYCOM_ICATREGISTER
|
||||
#define NO_PYCOM_ISERVICEPROVIDER
|
||||
#define NO_PYCOM_IPROPERTYSTORAGE
|
||||
#define NO_PYCOM_IPROPERTYSETSTORAGE
|
||||
#define NO_PYCOM_ENUMSTATPROPSTG
|
||||
|
||||
#include "ocidl.h"
|
||||
#include "oleauto.h"
|
||||
|
||||
#endif // MS_WINCE
|
||||
|
||||
#ifdef __MINGW32__
|
||||
// Special Mingw32 considerations.
|
||||
#define NO_PYCOM_ENUMSTATPROPSTG
|
||||
#define __try try
|
||||
#define __except catch
|
||||
#include <olectl.h>
|
||||
|
||||
#endif // __MINGW32__
|
||||
|
||||
#include <PyWinTypes.h> // Standard Win32 Types
|
||||
|
||||
#ifndef NO_PYCOM_IDISPATCHEX
|
||||
#include <dispex.h> // New header for IDispatchEx interface.
|
||||
#endif // NO_PYCOM_IDISPATCHEX
|
||||
|
||||
#if defined(MAINWIN)
|
||||
// Mainwin seems to have 1/2 the VT_RECORD infrastructure in place
|
||||
#if !defined(VT_RECORD)
|
||||
#define VT_RECORD 36
|
||||
#define V_RECORDINFO(X) ((X)->brecVal.pRecInfo)
|
||||
#define V_RECORD(X) ((X)->brecVal.pvRecord)
|
||||
#else
|
||||
#pragma message( \
|
||||
"MAINWIN appears to have grown correct VT_RECORD " \
|
||||
"support. Please update PythonCOM.h accordingly")
|
||||
#endif // VT_RECORD
|
||||
#endif // MAINWIN
|
||||
|
||||
class PyIUnknown;
|
||||
// To make life interesting/complicated, I use C++ classes for
|
||||
// all Python objects. The main advantage is that I can derive
|
||||
// a PyIDispatch object from a PyIUnknown, etc. This provides a
|
||||
// clean C++ interface, and "automatically" provides all base
|
||||
// Python methods to "derived" Python types.
|
||||
//
|
||||
// Main disadvantage is that any extension DLLs will need to include
|
||||
// these headers, and link with this .lib
|
||||
//
|
||||
// Base class for (most of) the type objects.
|
||||
|
||||
class PYCOM_EXPORT PyComTypeObject : public PyTypeObject {
|
||||
public:
|
||||
PyComTypeObject(const char *name, PyComTypeObject *pBaseType, int typeSize, struct PyMethodDef *methodList,
|
||||
PyIUnknown *(*thector)(IUnknown *));
|
||||
~PyComTypeObject();
|
||||
|
||||
// is the given object an interface type object? (e.g. PyIUnknown)
|
||||
static BOOL is_interface_type(PyObject *ob);
|
||||
|
||||
public:
|
||||
PyIUnknown *(*ctor)(IUnknown *);
|
||||
};
|
||||
|
||||
// A type used for interfaces that can automatically provide enumerators
|
||||
// (ie, they themselves aren't enumerable, but do have a suitable default
|
||||
// method that returns a PyIEnum object
|
||||
class PYCOM_EXPORT PyComEnumProviderTypeObject : public PyComTypeObject {
|
||||
public:
|
||||
PyComEnumProviderTypeObject(const char *name, PyComTypeObject *pBaseType, int typeSize,
|
||||
struct PyMethodDef *methodList, PyIUnknown *(*thector)(IUnknown *),
|
||||
const char *enum_method_name);
|
||||
static PyObject *iter(PyObject *self);
|
||||
const char *enum_method_name;
|
||||
};
|
||||
|
||||
// A type used for PyIEnum interfaces
|
||||
class PYCOM_EXPORT PyComEnumTypeObject : public PyComTypeObject {
|
||||
public:
|
||||
static PyObject *iter(PyObject *self);
|
||||
static PyObject *iternext(PyObject *self);
|
||||
PyComEnumTypeObject(const char *name, PyComTypeObject *pBaseType, int typeSize, struct PyMethodDef *methodList,
|
||||
PyIUnknown *(*thector)(IUnknown *));
|
||||
};
|
||||
|
||||
// Very very base class - not COM specific - Should exist in the
|
||||
// Python core somewhere, IMO.
|
||||
class PYCOM_EXPORT PyIBase : public PyObject {
|
||||
public:
|
||||
// virtuals for Python support
|
||||
virtual PyObject *getattr(char *name);
|
||||
virtual int setattr(char *name, PyObject *v);
|
||||
virtual PyObject *repr();
|
||||
virtual int compare(PyObject *other)
|
||||
{
|
||||
if (this == other)
|
||||
return 0;
|
||||
if (this < other)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
// These iter are a little special, in that returning NULL means
|
||||
// use the implementation in the type
|
||||
virtual PyObject *iter() { return NULL; }
|
||||
virtual PyObject *iternext() { return NULL; }
|
||||
|
||||
protected:
|
||||
PyIBase();
|
||||
virtual ~PyIBase();
|
||||
|
||||
public:
|
||||
static BOOL is_object(PyObject *, PyComTypeObject *which);
|
||||
BOOL is_object(PyComTypeObject *which);
|
||||
static void dealloc(PyObject *ob);
|
||||
static PyObject *repr(PyObject *ob);
|
||||
static PyObject *getattro(PyObject *self, PyObject *name);
|
||||
static int setattro(PyObject *op, PyObject *obname, PyObject *v);
|
||||
static int cmp(PyObject *ob1, PyObject *ob2);
|
||||
static PyObject *richcmp(PyObject *ob1, PyObject *ob2, int op);
|
||||
};
|
||||
|
||||
/* Special Type objects */
|
||||
extern PYCOM_EXPORT PyTypeObject PyOleEmptyType; // equivalent to VT_EMPTY
|
||||
extern PYCOM_EXPORT PyTypeObject PyOleMissingType; // special Python handling.
|
||||
extern PYCOM_EXPORT PyTypeObject PyOleArgNotFoundType; // special VT_ERROR value
|
||||
extern PYCOM_EXPORT PyTypeObject PyOleNothingType; // special VT_ERROR value
|
||||
|
||||
// ALL of these set an appropriate Python error on bad return.
|
||||
|
||||
// Given a Python object that is a registered COM type, return a given
|
||||
// interface pointer on its underlying object, with a new reference added.
|
||||
PYCOM_EXPORT BOOL PyCom_InterfaceFromPyObject(PyObject *ob, REFIID iid, LPVOID *ppv, BOOL bNoneOK = TRUE);
|
||||
|
||||
// As above, but allows instance with "_oleobj_" attribute.
|
||||
PYCOM_EXPORT BOOL PyCom_InterfaceFromPyInstanceOrObject(PyObject *ob, REFIID iid, LPVOID *ppv, BOOL bNoneOK = TRUE);
|
||||
|
||||
// Release an arbitary COM pointer.
|
||||
// NOTE: the PRECALL/POSTCALL stuff is probably not strictly necessary
|
||||
// since the PyGILSTATE stuff has been in place (and even then, it only
|
||||
// mattered when it was the last Release() on a Python implemented object)
|
||||
#define PYCOM_RELEASE(pUnk) \
|
||||
{ \
|
||||
if (pUnk) { \
|
||||
PY_INTERFACE_PRECALL; \
|
||||
(pUnk)->Release(); \
|
||||
PY_INTERFACE_POSTCALL; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Given an IUnknown and an Interface ID, create and return an object
|
||||
// of the appropriate type. eg IID_Unknown->PyIUnknown,
|
||||
// IID_IDispatch->PyIDispatch, etc.
|
||||
// Uses a map that external extension DLLs can populate with their IID/type.
|
||||
// Under the principal of least surprise, this will return Py_None is punk is NULL.
|
||||
// Otherwise, a valid PyI*, but with NULL m_obj (and therefore totally useless)
|
||||
// object would be created.
|
||||
// BOOL bAddRef indicates if a COM reference count should be added to the IUnknown.
|
||||
// This depends purely on the context in which it is called. If the IUnknown is obtained
|
||||
// from a function that creates a new ref (eg, CoCreateInstance()) then you should use
|
||||
// FALSE. If you receive the pointer as (eg) a param to a gateway function, then
|
||||
// you normally need to pass TRUE, as this is truly a new reference.
|
||||
// *** ALWAYS take the time to get this right. ***
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromIUnknown(IUnknown *punk, REFIID riid, BOOL bAddRef = FALSE);
|
||||
|
||||
// VARIANT <-> PyObject conversion utilities.
|
||||
PYCOM_EXPORT BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var);
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromVariant(const VARIANT *var);
|
||||
|
||||
// PROPVARIANT
|
||||
PYCOM_EXPORT PyObject *PyObject_FromPROPVARIANT(PROPVARIANT *pVar);
|
||||
PYCOM_EXPORT PyObject *PyObject_FromPROPVARIANTs(PROPVARIANT *pVars, ULONG cVars);
|
||||
PYCOM_EXPORT BOOL PyObject_AsPROPVARIANT(PyObject *ob, PROPVARIANT *pVar);
|
||||
|
||||
// Other conversion helpers...
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromSTATSTG(STATSTG *pStat);
|
||||
PYCOM_EXPORT BOOL PyCom_PyObjectAsSTATSTG(PyObject *ob, STATSTG *pStat, DWORD flags = 0);
|
||||
PYCOM_EXPORT BOOL PyCom_SAFEARRAYFromPyObject(PyObject *obj, SAFEARRAY **ppSA, VARENUM vt = VT_VARIANT);
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromSAFEARRAY(SAFEARRAY *psa, VARENUM vt = VT_VARIANT);
|
||||
#ifndef NO_PYCOM_STGOPTIONS
|
||||
PYCOM_EXPORT BOOL PyCom_PyObjectAsSTGOPTIONS(PyObject *obstgoptions, STGOPTIONS **ppstgoptions);
|
||||
#endif
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromSTATPROPSETSTG(STATPROPSETSTG *pStat);
|
||||
PYCOM_EXPORT BOOL PyCom_PyObjectAsSTATPROPSETSTG(PyObject *, STATPROPSETSTG *);
|
||||
|
||||
// Currency support.
|
||||
PYCOM_EXPORT PyObject *PyObject_FromCurrency(CURRENCY &cy);
|
||||
PYCOM_EXPORT BOOL PyObject_AsCurrency(PyObject *ob, CURRENCY *pcy);
|
||||
|
||||
// OLEMENUGROUPWIDTHS are used by axcontrol, shell, etc
|
||||
PYCOM_EXPORT BOOL PyObject_AsOLEMENUGROUPWIDTHS(PyObject *oblpMenuWidths, OLEMENUGROUPWIDTHS *pWidths);
|
||||
PYCOM_EXPORT PyObject *PyObject_FromOLEMENUGROUPWIDTHS(const OLEMENUGROUPWIDTHS *pWidths);
|
||||
|
||||
/* Functions for Initializing COM, and also letting the core know about it!
|
||||
*/
|
||||
PYCOM_EXPORT HRESULT PyCom_CoInitializeEx(LPVOID reserved, DWORD dwInit);
|
||||
PYCOM_EXPORT HRESULT PyCom_CoInitialize(LPVOID reserved);
|
||||
PYCOM_EXPORT void PyCom_CoUninitialize();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Error related functions
|
||||
|
||||
// Client related functions - generally called by interfaces before
|
||||
// they return NULL back to Python to indicate the error.
|
||||
// All these functions return NULL so interfaces can generally
|
||||
// just "return PyCom_BuildPyException(hr, punk, IID_IWhatever)"
|
||||
|
||||
// Uses the HRESULT, and IErrorInfo interfaces if available to
|
||||
// create and set a pythoncom.com_error.
|
||||
PYCOM_EXPORT PyObject *PyCom_BuildPyException(HRESULT hr, IUnknown *pUnk = NULL, REFIID iid = IID_NULL);
|
||||
|
||||
// Uses the HRESULT and an EXCEPINFO structure to create and
|
||||
// set a pythoncom.com_error.
|
||||
PYCOM_EXPORT PyObject *PyCom_BuildPyExceptionFromEXCEPINFO(HRESULT hr, EXCEPINFO *pexcepInfo, UINT nArgErr = (UINT)-1);
|
||||
|
||||
// Sets a pythoncom.internal_error - no one should ever see these!
|
||||
PYCOM_EXPORT PyObject *PyCom_BuildInternalPyException(char *msg);
|
||||
|
||||
// Log an error to a Python logger object if one can be found, or
|
||||
// to stderr if no log available.
|
||||
// If logProvider is not NULL, we will call a "_GetLogger_()" method on it.
|
||||
// If logProvider is NULL, we attempt to fetch "win32com.logger".
|
||||
// If they do not exist, return None, or raise an error fetching them
|
||||
// (or even writing to them once fetched), the message still goes to stderr.
|
||||
// NOTE: By default, win32com does *not* provide a logger, so default is that
|
||||
// all errors are written to stdout.
|
||||
// This will *not* write a record if a COM Server error is current.
|
||||
PYCOM_EXPORT void PyCom_LoggerNonServerException(PyObject *logProvider, const char *fmt, ...);
|
||||
|
||||
// Write an error record, including exception. This will write an error
|
||||
// record even if a COM server error is current.
|
||||
PYCOM_EXPORT void PyCom_LoggerException(PyObject *logProvider, const char *fmt, ...);
|
||||
|
||||
// Write a warning record - in general this does *not* mean a call failed, but
|
||||
// still is something in the programmers control that they should change.
|
||||
// XXX - if an exception is pending when this is called, the traceback will
|
||||
// also be written. This is undesirable and will be changed should this
|
||||
// start being a problem.
|
||||
PYCOM_EXPORT void PyCom_LoggerWarning(PyObject *logProvider, const char *fmt, ...);
|
||||
|
||||
// Server related error functions
|
||||
// These are supplied so that any Python errors we detect can be
|
||||
// converted into COM error information. The HRESULT returned should
|
||||
// be returned by the COM function, and these functions also set the
|
||||
// IErrorInfo interfaces, so the caller can extract more detailed
|
||||
// information about the Python exception.
|
||||
|
||||
// Set a COM exception, logging the exception if not an explicitly raised 'server' exception
|
||||
PYCOM_EXPORT HRESULT PyCom_SetAndLogCOMErrorFromPyException(const char *methodName, REFIID riid /* = IID_NULL */);
|
||||
PYCOM_EXPORT HRESULT PyCom_SetAndLogCOMErrorFromPyExceptionEx(PyObject *provider, const char *methodName,
|
||||
REFIID riid /* = IID_NULL */);
|
||||
|
||||
// Used in gateways to SetErrorInfo() with a simple HRESULT, then return it.
|
||||
// The description is generally only useful for debugging purposes,
|
||||
// and if you are debugging via a server that supports IErrorInfo (like Python :-)
|
||||
// NOTE: this function is usuable from outside the Python context
|
||||
PYCOM_EXPORT HRESULT PyCom_SetCOMErrorFromSimple(HRESULT hr, REFIID riid = IID_NULL, const char *description = NULL);
|
||||
|
||||
// Used in gateways to SetErrorInfo() the current Python exception, and
|
||||
// (assuming not a server error explicitly raised) also logs an error
|
||||
// to stdout/win32com.logger.
|
||||
// NOTE: this function assumes GIL held
|
||||
PYCOM_EXPORT HRESULT PyCom_SetCOMErrorFromPyException(REFIID riid = IID_NULL);
|
||||
|
||||
// A couple of EXCEPINFO helpers - could be private to IDispatch
|
||||
// if it wasnt for the AXScript support (and ITypeInfo if we get around to that :-)
|
||||
// These functions do not set any error states to either Python or
|
||||
// COM - they simply convert to/from PyObjects and EXCEPINFOs
|
||||
|
||||
// Use the current Python exception to fill an EXCEPINFO structure.
|
||||
PYCOM_EXPORT void PyCom_ExcepInfoFromPyException(EXCEPINFO *pExcepInfo);
|
||||
|
||||
// Fill in an EXCEPINFO structure from a Python instance or tuple object.
|
||||
// (ie, similar to the above, except the Python exception object is specified,
|
||||
// rather than using the "current"
|
||||
PYCOM_EXPORT BOOL PyCom_ExcepInfoFromPyObject(PyObject *obExcepInfo, EXCEPINFO *pexcepInfo, HRESULT *phresult = NULL);
|
||||
|
||||
// Create a Python object holding the exception information. The exception
|
||||
// information is *not* freed by this function. Python exceptions are
|
||||
// raised and NULL is returned if an error occurs.
|
||||
PYCOM_EXPORT PyObject *PyCom_PyObjectFromExcepInfo(const EXCEPINFO *pexcepInfo);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// External C++ helpers - these helpers are for other DLLs which
|
||||
// may need similar functionality, but dont want to duplicate all
|
||||
|
||||
// This helper is for an application that has an IDispatch, and COM arguments
|
||||
// and wants to call a Python function. It is assumed the caller can map the IDispatch
|
||||
// to a Python object, so the Python handler is passed.
|
||||
// Args:
|
||||
// handler : A Python callable object.
|
||||
// dispparms : the COM arguments.
|
||||
// pVarResult : The variant for the return value of the Python call.
|
||||
// pexcepinfo : Exception info the helper may fill out.
|
||||
// puArgErr : Argument error the helper may fill out on exception
|
||||
// addnArgs : Any additional arguments to the Python function. May be NULL.
|
||||
// If addnArgs is NULL, then it is assumed the Python call should be native -
|
||||
// ie, the COM args are packed as normal Python args to the call.
|
||||
// If addnArgs is NOT NULL, it is assumed the Python function itself is
|
||||
// a helper. This Python function will be called with 2 arguments - both
|
||||
// tuples - first one is the COM args, second is the addn args.
|
||||
PYCOM_EXPORT BOOL PyCom_MakeOlePythonCall(PyObject *handler, DISPPARAMS FAR *params, VARIANT FAR *pVarResult,
|
||||
EXCEPINFO FAR *pexcepinfo, UINT FAR *puArgErr, PyObject *addnlArgs);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Various special purpose singletons
|
||||
class PYCOM_EXPORT PyOleEmpty : public PyObject {
|
||||
public:
|
||||
PyOleEmpty();
|
||||
};
|
||||
|
||||
class PYCOM_EXPORT PyOleMissing : public PyObject {
|
||||
public:
|
||||
PyOleMissing();
|
||||
};
|
||||
|
||||
class PYCOM_EXPORT PyOleArgNotFound : public PyObject {
|
||||
public:
|
||||
PyOleArgNotFound();
|
||||
};
|
||||
|
||||
class PYCOM_EXPORT PyOleNothing : public PyObject {
|
||||
public:
|
||||
PyOleNothing();
|
||||
};
|
||||
|
||||
// We need to dynamically create C++ Python objects
|
||||
// These helpers allow each type object to create it.
|
||||
#define MAKE_PYCOM_CTOR(classname) \
|
||||
static PyIUnknown *classname::PyObConstruct(IUnknown *pInitObj) { return new classname(pInitObj); }
|
||||
#define MAKE_PYCOM_CTOR_ERRORINFO(classname, iid) \
|
||||
static PyIUnknown *classname::PyObConstruct(IUnknown *pInitObj) { return new classname(pInitObj); } \
|
||||
static PyObject *SetPythonCOMError(PyObject *self, HRESULT hr) \
|
||||
{ \
|
||||
return PyCom_BuildPyException(hr, GetI(self), iid); \
|
||||
}
|
||||
#define GET_PYCOM_CTOR(classname) classname::PyObConstruct
|
||||
|
||||
// Macros that interfaces should use. PY_INTERFACE_METHOD at the top of the method
|
||||
// The other 2 wrap directly around the underlying method call.
|
||||
#define PY_INTERFACE_METHOD
|
||||
// Identical to Py_BEGIN_ALLOW_THREADS except no { !!!
|
||||
#define PY_INTERFACE_PRECALL PyThreadState *_save = PyEval_SaveThread();
|
||||
#define PY_INTERFACE_POSTCALL PyEval_RestoreThread(_save);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIUnknown
|
||||
class PYCOM_EXPORT PyIUnknown : public PyIBase {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyIUnknown);
|
||||
virtual PyObject *repr();
|
||||
virtual int compare(PyObject *other);
|
||||
|
||||
static IUnknown *GetI(PyObject *self);
|
||||
IUnknown *m_obj;
|
||||
static char *szErrMsgObjectReleased;
|
||||
static void SafeRelease(PyIUnknown *ob);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *QueryInterface(PyObject *self, PyObject *args);
|
||||
static PyObject *SafeRelease(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIUnknown(IUnknown *punk);
|
||||
~PyIUnknown();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIDispatch
|
||||
|
||||
class PYCOM_EXPORT PyIDispatch : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyIDispatch);
|
||||
static IDispatch *GetI(PyObject *self);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *Invoke(PyObject *self, PyObject *args);
|
||||
static PyObject *InvokeTypes(PyObject *self, PyObject *args);
|
||||
static PyObject *GetIDsOfNames(PyObject *self, PyObject *args);
|
||||
static PyObject *GetTypeInfo(PyObject *self, PyObject *args);
|
||||
static PyObject *GetTypeInfoCount(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIDispatch(IUnknown *pdisp);
|
||||
~PyIDispatch();
|
||||
};
|
||||
|
||||
#ifndef NO_PYCOM_IDISPATCHEX
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIDispatchEx
|
||||
|
||||
class PYCOM_EXPORT PyIDispatchEx : public PyIDispatch {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR_ERRORINFO(PyIDispatchEx, IID_IDispatchEx);
|
||||
static IDispatchEx *GetI(PyObject *self);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *GetDispID(PyObject *self, PyObject *args);
|
||||
static PyObject *InvokeEx(PyObject *self, PyObject *args);
|
||||
static PyObject *DeleteMemberByName(PyObject *self, PyObject *args);
|
||||
static PyObject *DeleteMemberByDispID(PyObject *self, PyObject *args);
|
||||
static PyObject *GetMemberProperties(PyObject *self, PyObject *args);
|
||||
static PyObject *GetMemberName(PyObject *self, PyObject *args);
|
||||
static PyObject *GetNextDispID(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIDispatchEx(IUnknown *pdisp);
|
||||
~PyIDispatchEx();
|
||||
};
|
||||
#endif // NO_PYCOM_IDISPATCHEX
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIClassFactory
|
||||
|
||||
class PYCOM_EXPORT PyIClassFactory : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyIClassFactory);
|
||||
static IClassFactory *GetI(PyObject *self);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *CreateInstance(PyObject *self, PyObject *args);
|
||||
static PyObject *LockServer(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIClassFactory(IUnknown *pdisp);
|
||||
~PyIClassFactory();
|
||||
};
|
||||
|
||||
#ifndef NO_PYCOM_IPROVIDECLASSINFO
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIProvideTypeInfo
|
||||
|
||||
class PYCOM_EXPORT PyIProvideClassInfo : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyIProvideClassInfo);
|
||||
static IProvideClassInfo *GetI(PyObject *self);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *GetClassInfo(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIProvideClassInfo(IUnknown *pdisp);
|
||||
~PyIProvideClassInfo();
|
||||
};
|
||||
|
||||
class PYCOM_EXPORT PyIProvideClassInfo2 : public PyIProvideClassInfo {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyIProvideClassInfo2);
|
||||
static IProvideClassInfo2 *GetI(PyObject *self);
|
||||
static PyComTypeObject type;
|
||||
|
||||
// The Python methods
|
||||
static PyObject *GetGUID(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIProvideClassInfo2(IUnknown *pdisp);
|
||||
~PyIProvideClassInfo2();
|
||||
};
|
||||
#endif // NO_PYCOM_IPROVIDECLASSINFO
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyITypeInfo
|
||||
class PYCOM_EXPORT PyITypeInfo : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyITypeInfo);
|
||||
static PyComTypeObject type;
|
||||
static ITypeInfo *GetI(PyObject *self);
|
||||
|
||||
PyObject *GetContainingTypeLib();
|
||||
PyObject *GetDocumentation(MEMBERID);
|
||||
PyObject *GetRefTypeInfo(HREFTYPE href);
|
||||
PyObject *GetRefTypeOfImplType(int index);
|
||||
PyObject *GetFuncDesc(int pos);
|
||||
PyObject *GetIDsOfNames(OLECHAR FAR *FAR *, int);
|
||||
PyObject *GetNames(MEMBERID);
|
||||
PyObject *GetTypeAttr();
|
||||
PyObject *GetVarDesc(int pos);
|
||||
PyObject *GetImplTypeFlags(int index);
|
||||
PyObject *GetTypeComp();
|
||||
|
||||
protected:
|
||||
PyITypeInfo(IUnknown *);
|
||||
~PyITypeInfo();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyITypeComp
|
||||
class PYCOM_EXPORT PyITypeComp : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyITypeComp);
|
||||
static PyComTypeObject type;
|
||||
static ITypeComp *GetI(PyObject *self);
|
||||
|
||||
PyObject *Bind(OLECHAR *szName, unsigned short wflags);
|
||||
PyObject *BindType(OLECHAR *szName);
|
||||
|
||||
protected:
|
||||
PyITypeComp(IUnknown *);
|
||||
~PyITypeComp();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class CPyTypeLib
|
||||
|
||||
class PYCOM_EXPORT PyITypeLib : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR(PyITypeLib);
|
||||
static PyComTypeObject type;
|
||||
static ITypeLib *GetI(PyObject *self);
|
||||
|
||||
PyObject *GetLibAttr();
|
||||
PyObject *GetDocumentation(int pos);
|
||||
PyObject *GetTypeInfo(int pos);
|
||||
PyObject *GetTypeInfoCount();
|
||||
PyObject *GetTypeInfoOfGuid(REFGUID guid);
|
||||
PyObject *GetTypeInfoType(int pos);
|
||||
PyObject *GetTypeComp();
|
||||
|
||||
protected:
|
||||
PyITypeLib(IUnknown *);
|
||||
~PyITypeLib();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PyIConnectionPoint
|
||||
|
||||
class PYCOM_EXPORT PyIConnectionPoint : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR_ERRORINFO(PyIConnectionPoint, IID_IConnectionPoint);
|
||||
static PyComTypeObject type;
|
||||
static IConnectionPoint *GetI(PyObject *self);
|
||||
|
||||
static PyObject *GetConnectionInterface(PyObject *self, PyObject *args);
|
||||
static PyObject *GetConnectionPointContainer(PyObject *self, PyObject *args);
|
||||
static PyObject *Advise(PyObject *self, PyObject *args);
|
||||
static PyObject *Unadvise(PyObject *self, PyObject *args);
|
||||
static PyObject *EnumConnections(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIConnectionPoint(IUnknown *);
|
||||
~PyIConnectionPoint();
|
||||
};
|
||||
|
||||
class PYCOM_EXPORT PyIConnectionPointContainer : public PyIUnknown {
|
||||
public:
|
||||
MAKE_PYCOM_CTOR_ERRORINFO(PyIConnectionPointContainer, IID_IConnectionPointContainer);
|
||||
static PyComTypeObject type;
|
||||
static IConnectionPointContainer *GetI(PyObject *self);
|
||||
|
||||
static PyObject *EnumConnectionPoints(PyObject *self, PyObject *args);
|
||||
static PyObject *FindConnectionPoint(PyObject *self, PyObject *args);
|
||||
|
||||
protected:
|
||||
PyIConnectionPointContainer(IUnknown *);
|
||||
~PyIConnectionPointContainer();
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// class PythonOleArgHelper
|
||||
//
|
||||
// A PythonOleArgHelper is used primarily to help out Python helpers
|
||||
// which need to convert from a Python object when the specific OLE
|
||||
// type is known - eg, when a TypeInfo is available.
|
||||
//
|
||||
// The type of conversion determines who owns what buffers etc. I wish BYREF didnt exist :-)
|
||||
typedef enum {
|
||||
// We dont know what sort of conversion it is yet.
|
||||
POAH_CONVERT_UNKNOWN,
|
||||
// A PyObject is given, we convert to a VARIANT, make the COM call, then BYREFs back to a PyObject
|
||||
// ie, this is typically a "normal" COM call, where Python initiates the call
|
||||
POAH_CONVERT_FROM_PYOBJECT,
|
||||
// A VARIANT is given, we convert to a PyObject, make the Python call, then BYREFs back to a VARIANT.
|
||||
// ie, this is typically handling a COM event, where COM itself initiates the call.
|
||||
POAH_CONVERT_FROM_VARIANT,
|
||||
} POAH_CONVERT_DIRECTION;
|
||||
|
||||
class PYCOM_EXPORT PythonOleArgHelper {
|
||||
public:
|
||||
PythonOleArgHelper();
|
||||
~PythonOleArgHelper();
|
||||
BOOL ParseTypeInformation(PyObject *reqdObjectTuple);
|
||||
|
||||
// Using this call with reqdObject != NULL will check the existing
|
||||
// VT_ of the variant. If not VT_EMPTY, then the result will be coerced to
|
||||
// that type. This contrasts with PyCom_PyObjectToVariant which just
|
||||
// uses the Python type to determine the variant type.
|
||||
BOOL MakeObjToVariant(PyObject *obj, VARIANT *var, PyObject *reqdObjectTuple = NULL);
|
||||
PyObject *MakeVariantToObj(VARIANT *var);
|
||||
|
||||
VARTYPE m_reqdType;
|
||||
BOOL m_bParsedTypeInfo;
|
||||
BOOL m_bIsOut;
|
||||
POAH_CONVERT_DIRECTION m_convertDirection;
|
||||
PyObject *m_pyVariant; // if non-null, a win32com.client.VARIANT
|
||||
union {
|
||||
void *m_pValueHolder;
|
||||
short m_sBuf;
|
||||
long m_lBuf;
|
||||
LONGLONG m_llBuf;
|
||||
VARIANT_BOOL m_boolBuf;
|
||||
double m_dBuf;
|
||||
float m_fBuf;
|
||||
IDispatch *m_dispBuf;
|
||||
IUnknown *m_unkBuf;
|
||||
SAFEARRAY *m_arrayBuf;
|
||||
VARIANT *m_varBuf;
|
||||
DATE m_dateBuf;
|
||||
CY m_cyBuf;
|
||||
};
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// global functions and variables
|
||||
PYCOM_EXPORT BOOL MakePythonArgumentTuples(PyObject **pArgs, PythonOleArgHelper **ppHelpers, PyObject **pNamedArgs,
|
||||
PythonOleArgHelper **ppNamedHelpers, DISPPARAMS FAR *params);
|
||||
|
||||
// Convert a Python object to a BSTR - allow embedded NULLs, None, etc.
|
||||
PYCOM_EXPORT BOOL PyCom_BstrFromPyObject(PyObject *stringObject, BSTR *pResult, BOOL bNoneOK = FALSE);
|
||||
|
||||
// MakeBstrToObj - convert a BSTR into a Python string.
|
||||
//
|
||||
// ONLY USE THIS FOR TRUE BSTR's - Use the fn below for OLECHAR *'s.
|
||||
// NOTE - does not use standard macros, so NULLs get through!
|
||||
PYCOM_EXPORT PyObject *MakeBstrToObj(const BSTR bstr);
|
||||
|
||||
// Size info is available (eg, a fn returns a string and also fills in a size variable)
|
||||
PYCOM_EXPORT PyObject *MakeOLECHARToObj(const OLECHAR *str, int numChars);
|
||||
|
||||
// No size info avail.
|
||||
PYCOM_EXPORT PyObject *MakeOLECHARToObj(const OLECHAR *str);
|
||||
|
||||
PYCOM_EXPORT void PyCom_LogF(const char *fmt, ...);
|
||||
|
||||
// Generic conversion from python sequence to VT_VECTOR array
|
||||
// Resulting array must be freed with CoTaskMemFree
|
||||
template <typename arraytype>
|
||||
BOOL SeqToVector(PyObject *ob, arraytype **pA, ULONG *pcount, BOOL (*converter)(PyObject *, arraytype *))
|
||||
{
|
||||
TmpPyObject seq = PyWinSequence_Tuple(ob, pcount);
|
||||
if (seq == NULL)
|
||||
return FALSE;
|
||||
*pA = (arraytype *)CoTaskMemAlloc(*pcount * sizeof(arraytype));
|
||||
if (*pA == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return FALSE;
|
||||
}
|
||||
for (ULONG i = 0; i < *pcount; i++) {
|
||||
PyObject *item = PyTuple_GET_ITEM((PyObject *)seq, i);
|
||||
if (!(*converter)(item, &(*pA)[i]))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif // __PYTHONCOM_H__
|
84
venv/Lib/site-packages/win32com/include/PythonCOMRegister.h
Normal file
84
venv/Lib/site-packages/win32com/include/PythonCOMRegister.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Support for PythonCOM and its extensions to register the interfaces,
|
||||
// gateways and IIDs it supports.
|
||||
//
|
||||
// The module can simply declare an array of type PyCom_InterfaceSupportInfo, then
|
||||
// use the macros to populate it.
|
||||
//
|
||||
// See Register.cpp and AXScript.cpp for examples on its use.
|
||||
|
||||
#ifndef __PYTHONCOMREGISTER_H__
|
||||
#define __PYTHONCOMREGISTER_H__
|
||||
|
||||
#include "PythonCOMServer.h" // Need defns in this file...
|
||||
|
||||
typedef struct {
|
||||
const GUID *pGUID; // The supported IID - required
|
||||
const char *interfaceName; // Name of the interface - required
|
||||
const char *iidName; // Name of the IID that goes into the dict. - required
|
||||
PyTypeObject *pTypeOb; // the type object for client PyI* side - NULL for server only support.
|
||||
pfnPyGatewayConstructor ctor; // Gateway (PyG*) interface constructor - NULL for client only support
|
||||
|
||||
} PyCom_InterfaceSupportInfo;
|
||||
|
||||
#define PYCOM_INTERFACE_IID_ONLY(ifc) \
|
||||
{ \
|
||||
&IID_I##ifc, "I" #ifc, "IID_I" #ifc, NULL, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_CLSID_ONLY(ifc) \
|
||||
{ \
|
||||
&CLSID_##ifc, "CLSID_" #ifc, "CLSID_" #ifc, NULL, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_CATID_ONLY(ifc) \
|
||||
{ \
|
||||
&CATID_##ifc, "CATID_" #ifc, "CATID_" #ifc, NULL, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_CLIENT_ONLY(ifc) \
|
||||
{ \
|
||||
&IID_I##ifc, "I" #ifc, "IID_I" #ifc, &PyI##ifc::type, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_SERVER_ONLY(ifc) \
|
||||
{ \
|
||||
&IID_I##ifc, "I" #ifc, "IID_I" #ifc, NULL, GET_PYGATEWAY_CTOR(PyG##ifc) \
|
||||
}
|
||||
#define PYCOM_INTERFACE_FULL(ifc) \
|
||||
{ \
|
||||
&IID_I##ifc, "I" #ifc, "IID_I" #ifc, &PyI##ifc::type, GET_PYGATEWAY_CTOR(PyG##ifc) \
|
||||
}
|
||||
|
||||
// Versions that use __uuidof() to get the IID, which seems to avoid the need
|
||||
// to link with a lib holding the IIDs. Note that almost all extensions
|
||||
// build with __uuidof() being the default; the build failed at 'shell' - so
|
||||
// we could consider making this the default and making the 'explicit' version
|
||||
// above the special case.
|
||||
#define PYCOM_INTERFACE_IID_ONLY_UUIDOF(ifc) \
|
||||
{ \
|
||||
&__uuidof(I##ifc), "I" #ifc, "IID_I" #ifc, NULL, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_CLIENT_ONLY_UUIDOF(ifc) \
|
||||
{ \
|
||||
&__uuidof(I##ifc), "I" #ifc, "IID_I" #ifc, &PyI##ifc::type, NULL \
|
||||
}
|
||||
#define PYCOM_INTERFACE_SERVER_ONLY_UUIDOF(ifc) \
|
||||
{ \
|
||||
&__uuidof(I##ifc), "I" #ifc, "IID_I" #ifc, NULL, GET_PYGATEWAY_CTOR(PyG##ifc) \
|
||||
}
|
||||
#define PYCOM_INTERFACE_FULL_UUIDOF(ifc) \
|
||||
{ \
|
||||
&__uuidof(I##ifc), "I" #ifc, "IID_I" #ifc, &PyI##ifc::type, GET_PYGATEWAY_CTOR(PyG##ifc) \
|
||||
}
|
||||
|
||||
// Prototypes for the register functions
|
||||
|
||||
// Register a PythonCOM extension module
|
||||
PYCOM_EXPORT int PyCom_RegisterExtensionSupport(PyObject *dict, const PyCom_InterfaceSupportInfo *pInterfaces,
|
||||
int numEntries);
|
||||
|
||||
// THESE SHOULD NO LONGER BE USED. Instead, use the functions above passing an
|
||||
// array of PyCom_InterfaceSupportInfo objects.
|
||||
|
||||
PYCOM_EXPORT int PyCom_RegisterClientType(PyTypeObject *typeOb, const GUID *guid);
|
||||
|
||||
HRESULT PYCOM_EXPORT PyCom_RegisterGatewayObject(REFIID iid, pfnPyGatewayConstructor ctor, const char *interfaceName);
|
||||
PYCOM_EXPORT int PyCom_IsGatewayRegistered(REFIID iid);
|
||||
|
||||
#endif /* __PYTHONCOMREGISTER_H__ */
|
176
venv/Lib/site-packages/win32com/include/PythonCOMServer.h
Normal file
176
venv/Lib/site-packages/win32com/include/PythonCOMServer.h
Normal file
|
@ -0,0 +1,176 @@
|
|||
#ifndef __PYTHONCOMSERVER_H__
|
||||
#define __PYTHONCOMSERVER_H__
|
||||
|
||||
// PythonCOMServer.h :Server side COM support
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#define DLLAcquireGlobalLock PyWin_AcquireGlobalLock
|
||||
#define DLLReleaseGlobalLock PyWin_ReleaseGlobalLock
|
||||
|
||||
void PYCOM_EXPORT PyCom_DLLAddRef(void);
|
||||
void PYCOM_EXPORT PyCom_DLLReleaseRef(void);
|
||||
|
||||
// Use this macro at the start of all gateway methods.
|
||||
#define PY_GATEWAY_METHOD CEnterLeavePython _celp
|
||||
|
||||
class PyGatewayBase;
|
||||
// Gateway constructors.
|
||||
// Each gateway must be able to be created from a "gateway constructor". This
|
||||
// is simply a function that takes a Python instance as as argument, and returns
|
||||
// a gateway object of the correct type. The MAKE_PYGATEWAY_CTOR is a helper that
|
||||
// will embed such a constructor in the class - however, this is not necessary -
|
||||
// _any_ function of the correct signature can be used.
|
||||
|
||||
typedef HRESULT (*pfnPyGatewayConstructor)(PyObject *PythonInstance, PyGatewayBase *, void **ppResult, REFIID iid);
|
||||
HRESULT PyCom_MakeRegisteredGatewayObject(REFIID iid, PyObject *instance, PyGatewayBase *base, void **ppv);
|
||||
|
||||
// A version of the above which support classes being derived from
|
||||
// other than IUnknown
|
||||
#define PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, gatewaybaseclass) \
|
||||
public: \
|
||||
static HRESULT classname::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *unkBase, void **ppResult, \
|
||||
REFIID iid) \
|
||||
{ \
|
||||
if (ppResult == NULL) \
|
||||
return E_INVALIDARG; \
|
||||
classname *newob = new classname(pPyInstance); \
|
||||
newob->m_pBaseObject = unkBase; \
|
||||
if (unkBase) \
|
||||
unkBase->AddRef(); \
|
||||
*ppResult = newob->ThisAsIID(iid); \
|
||||
return *ppResult ? S_OK : E_OUTOFMEMORY; \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
virtual IID GetIID(void) { return theIID; } \
|
||||
virtual void *ThisAsIID(IID iid) \
|
||||
{ \
|
||||
if (this == NULL) \
|
||||
return NULL; \
|
||||
if (iid == theIID) \
|
||||
return (IInterface *)this; \
|
||||
else \
|
||||
return gatewaybaseclass::ThisAsIID(iid); \
|
||||
} \
|
||||
STDMETHOD_(ULONG, AddRef)(void) { return gatewaybaseclass::AddRef(); } \
|
||||
STDMETHOD_(ULONG, Release)(void) { return gatewaybaseclass::Release(); } \
|
||||
STDMETHOD(QueryInterface)(REFIID iid, void **obj) { return gatewaybaseclass::QueryInterface(iid, obj); };
|
||||
|
||||
// This is the "old" version to use, or use it if you derive
|
||||
// directly from PyGatewayBase
|
||||
#define PYGATEWAY_MAKE_SUPPORT(classname, IInterface, theIID) \
|
||||
PYGATEWAY_MAKE_SUPPORT2(classname, IInterface, theIID, PyGatewayBase)
|
||||
|
||||
#define GET_PYGATEWAY_CTOR(classname) classname::PyGatewayConstruct
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Disable an OK warning...
|
||||
#pragma warning(disable : 4275)
|
||||
// warning C4275: non dll-interface struct 'IDispatch' used as base for dll-interface class 'PyGatewayBase'
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Helper interface for fetching a Python object from a gateway
|
||||
|
||||
extern const GUID IID_IInternalUnwrapPythonObject;
|
||||
|
||||
interface IInternalUnwrapPythonObject : public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD(Unwrap)(PyObject * *ppPyObject) = 0;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// PyGatewayBase
|
||||
//
|
||||
// Base class for all gateways.
|
||||
//
|
||||
class PYCOM_EXPORT PyGatewayBase :
|
||||
#ifndef NO_PYCOM_IDISPATCHEX
|
||||
public IDispatchEx, // IDispatch comes along for the ride!
|
||||
#else
|
||||
public IDispatch, // No IDispatchEx - must explicitely use IDispatch
|
||||
#endif
|
||||
public ISupportErrorInfo,
|
||||
public IInternalUnwrapPythonObject {
|
||||
protected:
|
||||
PyGatewayBase(PyObject *instance);
|
||||
virtual ~PyGatewayBase();
|
||||
|
||||
// Invoke the Python method (via the policy object)
|
||||
STDMETHOD(InvokeViaPolicy)(const char *szMethodName, PyObject **ppResult = NULL, const char *szFormat = NULL, ...);
|
||||
|
||||
public:
|
||||
// IUnknown
|
||||
STDMETHOD_(ULONG, AddRef)(void);
|
||||
STDMETHOD_(ULONG, Release)(void);
|
||||
STDMETHOD(QueryInterface)(REFIID iid, void **obj);
|
||||
|
||||
// IDispatch
|
||||
STDMETHOD(GetTypeInfoCount)(UINT FAR *pctInfo);
|
||||
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR *FAR *pptInfo);
|
||||
STDMETHOD(GetIDsOfNames)(REFIID refiid, OLECHAR FAR *FAR *rgszNames, UINT cNames, LCID lcid, DISPID FAR *rgdispid);
|
||||
STDMETHOD(Invoke)
|
||||
(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *params, VARIANT FAR *pVarResult,
|
||||
EXCEPINFO FAR *pexcepinfo, UINT FAR *puArgErr);
|
||||
|
||||
// IDispatchEx
|
||||
#ifndef NO_PYCOM_IDISPATCHEX
|
||||
STDMETHOD(GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
|
||||
STDMETHOD(InvokeEx)
|
||||
(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
|
||||
STDMETHOD(DeleteMemberByName)(BSTR bstr, DWORD grfdex);
|
||||
STDMETHOD(DeleteMemberByDispID)(DISPID id);
|
||||
STDMETHOD(GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
|
||||
STDMETHOD(GetMemberName)(DISPID id, BSTR *pbstrName);
|
||||
STDMETHOD(GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
|
||||
STDMETHOD(GetNameSpaceParent)(IUnknown **ppunk);
|
||||
#endif // NO_PYCOM_IDISPATCHEX
|
||||
// ISupportErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// IInternalUnwrapPythonObject
|
||||
STDMETHOD(Unwrap)(PyObject **ppPyObject);
|
||||
|
||||
// Basically just PYGATEWAY_MAKE_SUPPORT(PyGatewayBase, IDispatch, IID_IDispatch);
|
||||
// but with special handling as its the base class.
|
||||
static HRESULT PyGatewayBase::PyGatewayConstruct(PyObject *pPyInstance, PyGatewayBase *gatewayBase, void **ppResult,
|
||||
REFIID iid)
|
||||
{
|
||||
if (ppResult == NULL)
|
||||
return E_INVALIDARG;
|
||||
PyGatewayBase *obNew = new PyGatewayBase(pPyInstance);
|
||||
obNew->m_pBaseObject = gatewayBase;
|
||||
if (gatewayBase)
|
||||
gatewayBase->AddRef();
|
||||
*ppResult = (IDispatch *)obNew;
|
||||
return *ppResult ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
// Currently this is used only for ISupportErrorInfo,
|
||||
// so hopefully this will never be called in this base class.
|
||||
// (however, this is not a rule, so we wont assert or anything!)
|
||||
virtual IID GetIID(void) { return IID_IUnknown; }
|
||||
virtual void *ThisAsIID(IID iid);
|
||||
// End of PYGATEWAY_MAKE_SUPPORT
|
||||
PyObject *m_pPyObject;
|
||||
PyGatewayBase *m_pBaseObject;
|
||||
|
||||
private:
|
||||
LONG m_cRef;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4275)
|
||||
#endif // _MSC_VER
|
||||
|
||||
// B/W compat hack for gateways.
|
||||
#define PyCom_HandlePythonFailureToCOM() \
|
||||
PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, "<unknown>", GetIID())
|
||||
|
||||
// F/W compat hack for gateways! Must be careful about updating
|
||||
// PyGatewayBase vtable, so a slightly older pythoncomXX.dll will work
|
||||
// with slightly later extensions. So use a #define.
|
||||
#define MAKE_PYCOM_GATEWAY_FAILURE_CODE(method_name) \
|
||||
PyCom_SetAndLogCOMErrorFromPyExceptionEx(this->m_pPyObject, method_name, GetIID())
|
||||
|
||||
#endif /* __PYTHONCOMSERVER_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue