@pymethod object|PyIDispatch|InvokeTypes|Invokes a DISPID, using the passed arguments and type descriptions.
| 290 | |
| 291 | // @pymethod object|PyIDispatch|InvokeTypes|Invokes a DISPID, using the passed arguments and type descriptions. |
| 292 | PyObject * PyIDispatch::InvokeTypes(PyObject *self, PyObject *args) |
| 293 | { |
| 294 | /* InvokeType(dispid, lcid, wflags, ELEMDESC resultType, ELEMDESC[] argTypes, arg1, arg2...) */ |
| 295 | PyErr_Clear(); |
| 296 | int argc = PyObject_Length(args); |
| 297 | if ( argc == -1 ) |
| 298 | return NULL; |
| 299 | if ( argc < 5 ) |
| 300 | return PyErr_Format(PyExc_TypeError, "not enough arguments (at least 5 needed)"); |
| 301 | |
| 302 | // @pyparm int|dispid||The dispid to use. Please see <om PyIDispatch.Invoke>. |
| 303 | DISPID dispid = PyInt_AsLong(PyTuple_GET_ITEM(args, 0)); |
| 304 | // @pyparm int|lcid||The locale ID. Please see <om PyIDispatch.Invoke>. |
| 305 | LCID lcid = PyInt_AsLong(PyTuple_GET_ITEM(args, 1)); |
| 306 | // @pyparm int|wFlags||Flags for the call. Please see <om PyIDispatch.Invoke>. |
| 307 | UINT wFlags = PyInt_AsLong(PyTuple_GET_ITEM(args, 2)); |
| 308 | // @pyparm tuple|resultTypeDesc||A tuple describing the type of the |
| 309 | // result. See the comments for more information. |
| 310 | PyObject *resultElemDesc = PyTuple_GET_ITEM(args, 3); |
| 311 | // @pyparm (tuple, ...)|typeDescs||A sequence of tuples describing |
| 312 | // the types of the parameters for the function. See the comments |
| 313 | // for more information. |
| 314 | PyObject *argsElemDescArray = PyTuple_GET_ITEM(args, 4); |
| 315 | // @pyparm object, ...|args||The args to the function. |
| 316 | if ( PyErr_Occurred() ) |
| 317 | return NULL; |
| 318 | int numArgs; |
| 319 | int argTypesLen = PyObject_Length(argsElemDescArray); |
| 320 | if (!PyTuple_Check(argsElemDescArray) || argTypesLen<argc-5) |
| 321 | return PyErr_Format(PyExc_TypeError, "The array of argument types must be a tuple whose size is <= to the number of arguments."); |
| 322 | // See how many _real_ entries - count until end or |
| 323 | // first param marked as Missing. |
| 324 | for (numArgs = 0;numArgs<argc-5; numArgs++) { |
| 325 | if (PyTuple_GET_ITEM(args, numArgs+5)->ob_type==&PyOleMissingType) { |
| 326 | break; |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | // these will all be cleared before returning |
| 331 | PythonOleArgHelper *ArgHelpers = NULL; |
| 332 | PyObject *result = NULL; |
| 333 | DISPID dispidNamed = DISPID_PROPERTYPUT; |
| 334 | DISPPARAMS dispparams = { NULL, NULL, 0, 0 }; |
| 335 | PythonOleArgHelper resultArgHelper; |
| 336 | |
| 337 | // This gets confusing. If we have typeinfo for a byref arg, but the |
| 338 | // arg is not specified by the user, then we _do_ present the arg to |
| 339 | // COM. If the arg does not exist, and it is not byref, then we do |
| 340 | // not present it _at_all - ie, the arg count does _not_ include it. |
| 341 | // So - first we must loop over the arg types, using this info to |
| 342 | // decide how big the arg array is! |
| 343 | |
| 344 | // If we have type info for an arg but not specified by the user, we will still process |
| 345 | // the arg fully. |
| 346 | // Note numArgs can not be > argTypesLen (as checked above) |
| 347 | UINT numArgArray = 0; |
| 348 | UINT i; |
| 349 |