ctypes-commit Mailing List for ctypes (Page 70)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2005-03-10 08:53:43
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18582 Modified Files: callproc.c Log Message: Document some internals about function calls. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** callproc.c 3 Feb 2005 19:30:30 -0000 1.126 --- callproc.c 10 Mar 2005 08:53:33 -0000 1.127 *************** *** 16,68 **** How are functions called, and how are parameters converted to C ? ! XXX to be rewritten..., no longer what happens! ! ! 1. (in CFuncPtr_call) restype and converters are got from self or stgdict. ! 2. If it's a COM method, the COM pointer is retrieved from the argument list. ! 3. If converters are there, the number of arguments is checked. ! 4. CallProc is called, for a COM method with a slice [1:-1] of the arg list. ! ! 5. An array of PyCArgObject pointers is allocated to hold all the converted arguments. ! 6. If converters are present, each argument is replaced by the result of passing the argument ! to the converter. ! 7. Each argument is passed to ConvParam, which creates a PyCArgObject. ! 8. Another PyCArgObject is allocated to hold the result of the function call. ! 9. PrepareResult() is called with the restype to fill out the tag field of the PyCArgObject. ! 10. _call_function_pointer is called. ! 11. GetResult() is called with the 'result' PyCArgObject' to convert the C data ! into a Python object. ! 12. All the PyCArgObjects are DECREF'd. ! What does PrepareResult and GetResult do? ! PrepareResult sets the 'tag' field of the PyCArgObject. ! - if no restype, assume integer, and set it to 'i'. ! - get the type's stgdict, if it has a getfunc and a string proto, ! set the tag to the format character (if it is in "bBhHiIlLqQdfP") ! - if it is a ctypes Pointer type, set it to 'P' ! - if it is callable, set it to 'i' (and later call it with the integer result) ! - otherwise assume integer, and set it to 'i' ! ! _call_function_pointer iterates over the PyCArgObject array, and pushed their values ! onto the stack, C type depending on the 'tag'. ! Depending if the result PyCArgObject's 'tag', the function is called and the result ! stored into the result's space. ! The libffi version of _call_function_pointer creates an array of ffi_type pointers, ! and fills it with ffi_type_xxx depending on the PyCArgObject's tag value. ! Same for the PyCArgObject's result tag, then calls the ffi_call function. ! ffi_call needs an array of ffi_type pointers, and an array of void* pointers ! pointing to the argument values (the value field of the PyCArgObject instances). ! GetResult doesn't use the 'tag' field, it examines restype again: - - If it is a ctypes pointer: create an empty instance, and memcpy() thze result into it. - - If the restype's stgdict has a getfunc, call it. - - If the restype is callable, call it with the integer result - */ --- 16,56 ---- How are functions called, and how are parameters converted to C ? ! 1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a ! keyword dictionary 'kwds'. ! 2. After several checks, _build_callargs() is called which returns another ! tuple 'callargs'. This may be the same tuple as 'inargs', a slice of ! 'inargs', or a completely fresh tuple, depending on several things (is is a ! COM method, are 'paramflags' available). ! 3. If [out] parameters are present in paramflags, _build_callargs also ! creates and returns another object, which is either a single object or a ! tuple, whcih will later be used to build the function return value. ! 4. _CallProc is then called with the 'callargs' tuple. _CallProc first ! allocates two arrays. The first is an array of 'struct argument' items, the ! second array has 'void *' entried. ! 5. If 'converters' are present (converters is a sequence of argtypes' ! from_param methods), for each item in 'callargs' converter is called and the ! result passed to ConvParam. If 'converters' are not present, each argument ! is directly passed to ConvParm. ! 6. For each arg, ConvParam stores the contained C data (or a pointer to it, ! for structures) into the 'struct argument' array. ! 7. Finally, a loop fills the 'void *' array so that each item points to the ! data contained in or pointed to by the 'struct argument' array. ! 8. The 'void *' argument array is what _call_function_pointer ! expects. _call_function_pointer then has very little to do - only some ! libffi specific stuff, then it calls ffi_call. ! So, there are 4 data structures holding processed arguments: ! - the inargs tuple (in CFuncPtr_call) ! - the callargs tuple (in CFuncPtr_call) ! - the 'struct argguments' array ! - the 'void *' array */ |
From: Thomas H. <th...@us...> - 2005-03-10 08:53:06
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18442 Modified Files: _ctypes.c Log Message: Error checking. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.217 retrieving revision 1.218 diff -C2 -d -r1.217 -r1.218 *** _ctypes.c 9 Mar 2005 16:42:50 -0000 1.217 --- _ctypes.c 10 Mar 2005 08:52:56 -0000 1.218 *************** *** 2691,2694 **** --- 2691,2696 ---- NULL); Py_DECREF(v); + if (ob == 0) + goto error; PyTuple_SET_ITEM(callargs, i, _byref(ob)); outmask |= (1 << i); |
From: Thomas H. <th...@us...> - 2005-03-09 20:35:36
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32640 Modified Files: setup.py Log Message: Actually use the verbosity option in testlocal. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.115 retrieving revision 1.116 diff -C2 -d -r1.115 -r1.116 *** setup.py 9 Mar 2005 20:31:53 -0000 1.115 --- setup.py 9 Mar 2005 20:35:26 -0000 1.116 *************** *** 232,236 **** sys.path = old_path suite = unittest.TestSuite(test_suites) ! unittest.TextTestRunner(verbosity=1).run(suite) # class test_local --- 232,236 ---- sys.path = old_path suite = unittest.TestSuite(test_suites) ! unittest.TextTestRunner(verbosity=self.verbosity).run(suite) # class test_local |
From: Thomas H. <th...@us...> - 2005-03-09 20:32:05
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31681 Modified Files: setup.py Log Message: Add a 'testlocal' command, which will run tests in the current process. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -d -r1.114 -r1.115 *** setup.py 9 Mar 2005 07:28:12 -0000 1.114 --- setup.py 9 Mar 2005 20:31:53 -0000 1.115 *************** *** 197,200 **** --- 197,239 ---- # class test + class test_local(test): + def run(self): + import glob, unittest, doctest, new + self.run_command('build') + + test_suites = [] + + for direct in self.test_dirs: + mask = os.path.join(direct, self.test_prefix + "*.py") + test_files = glob.glob(mask) + + print "=== Testing in '%s' ===" % direct + test_suites = [] + old_path = sys.path[:] + sys.path.insert(0, direct) + + try: + for pathname in test_files: + modname = os.path.splitext(pathname)[0].split(os.sep)[-1] + mod = __import__(modname) + try: + suite = doctest.DocTestSuite(mod) + except ValueError: + pass + else: + test_suites.append(suite) + for name, obj in mod.__dict__.items(): + if name.startswith("_"): + continue + if type(obj) is type(unittest.TestCase) \ + and issubclass(obj, unittest.TestCase): + test_suites.append(unittest.makeSuite(obj)) + finally: + sys.path = old_path + suite = unittest.TestSuite(test_suites) + unittest.TextTestRunner(verbosity=1).run(suite) + # class test_local + + class my_build_py(build_py.build_py): def find_package_modules (self, package, package_dir): *************** *** 456,460 **** cmdclass = {'test': test, 'build_py': my_build_py, 'build_ext': my_build_ext, ! 'clean': my_clean, 'install_data': my_install_data}, options = setup_options ) --- 495,500 ---- cmdclass = {'test': test, 'build_py': my_build_py, 'build_ext': my_build_ext, ! 'clean': my_clean, 'install_data': my_install_data, ! 'testlocal': test_local}, options = setup_options ) |
From: Thomas H. <th...@us...> - 2005-03-09 20:29:22
|
Update of /cvsroot/ctypes/ctypes/unittests/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30829 Modified Files: test_perf.py Log Message: small changes. Index: test_perf.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/com/test_perf.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_perf.py 16 Feb 2005 20:57:24 -0000 1.3 --- test_perf.py 9 Mar 2005 20:29:09 -0000 1.4 *************** *** 29,36 **** pass ! # get a FUNCDESC instance ! from ctypes.com.client import Dispatch ! d = Dispatch("InternetExplorer.Application") ! fd = d.Navigate.fd ################################################################ --- 29,38 ---- pass ! ! def get_fd(): ! # get a FUNCDESC instance ! from ctypes.com.client import Dispatch ! d = Dispatch("InternetExplorer.Application") ! return d.Navigate.fd ################################################################ *************** *** 50,64 **** timeit("-s", "from test_perf import RECT; rect = RECT()", "rect.lr") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam[0]") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam[1]") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam[1].tdesc") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam[1].tdesc.vt") ! timeit("-s", "from test_perf import fd", "fd.lprgelemdescParam[1].tdesc.u.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", --- 52,66 ---- timeit("-s", "from test_perf import RECT; rect = RECT()", "rect.lr") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam[0]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam[1]") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam[1].tdesc") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam[1].tdesc.vt") ! timeit("-s", "from test_perf import get_fd; fd = get_fd()", "fd.lprgelemdescParam[1].tdesc.u.lptdesc[0].vt") timeit('-s', "from ctypes import c_int", *************** *** 75,86 **** import comtypes except ImportError: ! sys.exit() ! timeit('-s', "from comtypes.automation import VARIANT", ! "VARIANT() # comtypes") ! timeit('-s', "from comtypes.automation import VARIANT; variant = VARIANT(3)", ! "variant.value # comtypes") ! timeit('-s', "from comtypes.automation import VARIANT; variant = VARIANT()", ! "variant.value = 3.14 # comtypes") # on my machine: --- 77,89 ---- import comtypes except ImportError: ! pass ! else: ! timeit('-s', "from comtypes.automation import VARIANT", ! "VARIANT() # comtypes") ! timeit('-s', "from comtypes.automation import VARIANT; variant = VARIANT(3)", ! "variant.value # comtypes") ! timeit('-s', "from comtypes.automation import VARIANT; variant = VARIANT()", ! "variant.value = 3.14 # comtypes") # on my machine: *************** *** 124,128 **** ## 5.25: variant.value # ctypes.com ## 11.20: variant.value = 3.14 # ctypes.com ! ## 1.00: VARIANT() # comtypes ## 4.99: variant.value # comtypes ## 11.40: variant.value = 3.14 # comtypes --- 127,131 ---- ## 5.25: variant.value # ctypes.com ## 11.20: variant.value = 3.14 # ctypes.com ! ## 2.08: VARIANT() # comtypes ## 4.99: variant.value # comtypes ## 11.40: variant.value = 3.14 # comtypes |
From: Thomas H. <th...@us...> - 2005-03-09 18:23:58
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30563 Modified Files: ctypes.h Log Message: Another todo comment. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** ctypes.h 9 Mar 2005 13:30:18 -0000 1.72 --- ctypes.h 9 Mar 2005 18:23:33 -0000 1.73 *************** *** 152,155 **** --- 152,163 ---- typedef struct { PyDictObject dict; /* first part identical to PyDictObject */ + /* The size and align fields are unneeded, they are in ffi_type as well. As + an experiment shows, it's trivial to get rid of them, the only thing to + remember is that in ArrayType_new the ffi_type fields must be filled in - + so far it was unneeded because libffi doesn't support arrays at all + (because they are passed as pointers to function calls anyway). But it's + too much risk to change that now, and there are other fields which doen't + belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?) + */ int size; /* number of bytes */ int align; /* alignment requirements */ |
From: Thomas H. <th...@us...> - 2005-03-09 16:43:22
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3430 Modified Files: test_paramflags.py Log Message: Support for [in, out] parameterflags added. Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_paramflags.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_paramflags.py 9 Mar 2005 13:49:43 -0000 1.3 --- test_paramflags.py 9 Mar 2005 16:43:12 -0000 1.4 *************** *** 122,133 **** dll = CDLL(_ctypes_test.__file__) ! # this is not yet implemented proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! self.failUnlessRaises(TypeError, ! lambda: proto("TwoOutArgs", dll, ! ((1, "a"), ! (3, "p1"), ! (1, "b"), ! (2, "p2")))) if __name__ == "__main__": --- 122,136 ---- dll = CDLL(_ctypes_test.__file__) ! # the COM idl of this function would be: ! # void TwoOutArgs([in] int a, [in, out] int *p1, [in] int b, [in, out] int *p2); proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) ! func = proto("TwoOutArgs", dll, ((1, "a"), (3, "p1"), (1, "b"), (3, "p2"))) ! # The function returns ((a + p1), (b + p2)) ! self.failUnlessEqual((3, 7), func(1, 2, 3, 4)) ! self.failUnlessEqual((10, 14), func(a=1, b=3, p1=9, p2=11)) ! # TypeError: required argument 'p1' is missing ! self.assertRaises(TypeError, lambda: func(a=1, b=3)) ! # TypeError: required argument 'p2' is missing ! self.assertRaises(TypeError, lambda: func(a=1, b=3, p1=3)) if __name__ == "__main__": |
From: Thomas H. <th...@us...> - 2005-03-09 16:43:01
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3325 Modified Files: _ctypes_test.c _ctypes.c Log Message: Support for [in, out] parameterflags added. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.216 retrieving revision 1.217 diff -C2 -d -r1.216 -r1.217 *** _ctypes.c 9 Mar 2005 13:49:42 -0000 1.216 --- _ctypes.c 9 Mar 2005 16:42:50 -0000 1.217 *************** *** 2,5 **** --- 2,8 ---- ToDo: + Get rid of the checker (and also the converters) field in CFuncPtrObject and + StgDictObject, and replace them by slot functions in StgDictObject. + think about a buffer-like object (memory? bytes?) *************** *** 2319,2322 **** --- 2322,2326 ---- case PARAMFLAG_FIN: case PARAMFLAG_FOUT: + case (PARAMFLAG_FIN | PARAMFLAG_FOUT): break; default: *************** *** 2639,2643 **** for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); ! PyObject *ob; int flag; char *name = NULL; --- 2643,2647 ---- for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); ! PyObject *ob, *v; int flag; char *name = NULL; *************** *** 2677,2680 **** --- 2681,2697 ---- - and then proceed in the same way as for an [out] parameter */ + ob = PyTuple_GET_ITEM(argtypes, i); + dict = PyType_stgdict(ob); + /* Create an instance of the pointed-to type */ + v = _get_arg(&inargs_index, name, defval, inargs, kwds); + if (v == 0) + goto error; + ob = PyObject_CallFunctionObjArgs(dict->proto, + v, + NULL); + Py_DECREF(v); + PyTuple_SET_ITEM(callargs, i, _byref(ob)); + outmask |= (1 << i); + break; default: PyErr_Format(PyExc_ValueError, Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** _ctypes_test.c 9 Mar 2005 13:49:42 -0000 1.45 --- _ctypes_test.c 9 Mar 2005 16:42:50 -0000 1.46 *************** *** 497,502 **** EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj) { ! *pi = a; ! *pj = b; } --- 497,502 ---- EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj) { ! *pi += a; ! *pj += b; } |
From: Thomas H. <th...@us...> - 2005-03-09 15:45:15
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20091 Modified Files: cfield.c Log Message: Todo comments. Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** cfield.c 16 Feb 2005 20:41:53 -0000 1.73 --- cfield.c 9 Mar 2005 15:45:05 -0000 1.74 *************** *** 1164,1167 **** --- 1164,1172 ---- }; + /* + Ideas: Implement VARIANT in this table, using 'V' code. + Use '?' as code for BOOL. + */ + struct fielddesc * getentry(char *fmt) |
From: Thomas H. <th...@us...> - 2005-03-09 13:50:21
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20542/unittests Modified Files: test_paramflags.py Log Message: Some fixes for linux. Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_paramflags.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_paramflags.py 9 Mar 2005 07:37:36 -0000 1.2 --- test_paramflags.py 9 Mar 2005 13:49:43 -0000 1.3 *************** *** 18,22 **** def check_retval(self, val): if val == 0: ! raise WinError() _check_retval_ = classmethod(check_retval) --- 18,24 ---- def check_retval(self, val): if val == 0: ! # WindowsError would be bettter, but the tests must run ! # crossplatform ! raise ValueError(val) _check_retval_ = classmethod(check_retval) *************** *** 56,60 **** self.assertEqual(type(func(hwnd_desktop)), RECT) # ...unless the call fails ! self.assertRaises(WindowsError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) --- 58,62 ---- self.assertEqual(type(func(hwnd_desktop)), RECT) # ...unless the call fails ! self.assertRaises(ValueError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) *************** *** 79,83 **** self.assertEqual(type(func(hwnd=hwnd_desktop)), RECT) # ...unless the call fails ! self.assertRaises(WindowsError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) --- 81,85 ---- self.assertEqual(type(func(hwnd=hwnd_desktop)), RECT) # ...unless the call fails ! self.assertRaises(ValueError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) |
From: Thomas H. <th...@us...> - 2005-03-09 13:49:58
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20542/source Modified Files: _ctypes.c _ctypes_test.c Log Message: Some fixes for linux. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.215 retrieving revision 1.216 diff -C2 -d -r1.215 -r1.216 *** _ctypes.c 9 Mar 2005 07:30:38 -0000 1.215 --- _ctypes.c 9 Mar 2005 13:49:42 -0000 1.216 *************** *** 2817,2820 **** --- 2817,2822 ---- argtypes = self->argtypes ? self->argtypes : dict->argtypes; + + pProc = *(void **)self->b_ptr; #ifdef MS_WIN32 if (self->index) { *************** *** 2846,2851 **** } pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000]; - } else { - pProc = *(void **)self->b_ptr; } #endif --- 2848,2851 ---- Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** _ctypes_test.c 9 Mar 2005 07:39:11 -0000 1.44 --- _ctypes_test.c 9 Mar 2005 13:49:42 -0000 1.45 *************** *** 491,495 **** return GetWindowRect(hwnd, prect); #else ! return hwnd == 0; #endif } --- 491,495 ---- return GetWindowRect(hwnd, prect); #else ! return hwnd != 0; #endif } |
From: Thomas H. <th...@us...> - 2005-03-09 13:30:32
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15745 Modified Files: ctypes.h Log Message: Add comments. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** ctypes.h 9 Mar 2005 07:39:11 -0000 1.71 --- ctypes.h 9 Mar 2005 13:30:18 -0000 1.72 *************** *** 157,162 **** ffi_type ffi_type; PyObject *proto; /* Only for Pointer/ArrayObject */ ! SETFUNC setfunc; /* Only for ArrayObject */ ! GETFUNC getfunc; /* Only for ArrayObject */ /* Following fields only used by CFuncPtrType_Type instances */ --- 157,162 ---- ffi_type ffi_type; PyObject *proto; /* Only for Pointer/ArrayObject */ ! SETFUNC setfunc; /* Only for simple objects */ ! GETFUNC getfunc; /* Only for simple objects */ /* Following fields only used by CFuncPtrType_Type instances */ *************** *** 169,172 **** --- 169,212 ---- } StgDictObject; + /**************************************************************** + StgDictObject fields + + setfunc and getfunc is only set for simple data types, it is copied from the + corresponding fielddesc entry. These are functions to set and get the value + in a memory block. + They should probably by used by other types as well. + + proto is only used for Pointer and Array types - it points to the item type + object. + + Probably all the magic ctypes methods (like from_param) should have C + callable wrappers in the StgDictObject. For simple data type, for example, + the fielddesc table could have entries for C codec from_param functions or + other methods as well, if a subtype overrides this method in Python at + construction time, or assigns to it later, tp_setattro should update the + StgDictObject function to a generic one. + + Currently, CFuncPtr types have 'converters' and 'checker' entries in their + type dict. They are only used to cache attributes from other entries, whihc + is wrong. + + One use case is the .value attribute that all simple types have. But some + complex structures, like VARIANT, represent a single value also, and should + have this attribute. + + Another use case is a _check_retval_ function, which is called when a ctypes + type is used as return type of a function to validate and compute the return + value. + + Common ctypes protocol: + + - setfunc: store a python value in a memory block + - getfunc: convert data from a memory block into a python value + + - checkfunc: validate and convert a return value from a function call + - toparamfunc: convert a python value into a function argument + + *****************************************************************/ + /* May return NULL, but does not set an exception! */ extern StgDictObject *PyType_stgdict(PyObject *obj); |
From: Thomas H. <th...@us...> - 2005-03-09 07:39:23
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21883 Modified Files: _ctypes_test.c ctypes.h Log Message: Fixes for linux. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** ctypes.h 8 Mar 2005 07:56:15 -0000 1.70 --- ctypes.h 9 Mar 2005 07:39:11 -0000 1.71 *************** *** 4,7 **** --- 4,10 ---- #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) + + #define PARAMFLAG_FIN 1 + #define PARAMFLAG_FOUT 2 #endif *************** *** 59,64 **** #ifdef MS_WIN32 int index; - PyObject *paramflags; #endif } CFuncPtrObject; --- 62,67 ---- #ifdef MS_WIN32 int index; #endif + PyObject *paramflags; } CFuncPtrObject; Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** _ctypes_test.c 9 Mar 2005 07:28:37 -0000 1.43 --- _ctypes_test.c 9 Mar 2005 07:39:11 -0000 1.44 *************** *** 430,433 **** --- 430,435 ---- long bottom; } RECT; + + typedef int HWND; #endif *************** *** 493,497 **** } ! EXPORT(int) TwoOutArgs(int a, int *pi, int b, int *pj) { *pi = a; --- 495,499 ---- } ! EXPORT(void) TwoOutArgs(int a, int *pi, int b, int *pj) { *pi = a; |
From: Thomas H. <th...@us...> - 2005-03-09 07:37:47
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21501 Modified Files: test_paramflags.py Log Message: TwoArgsOut returns None. Index: test_paramflags.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_paramflags.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_paramflags.py 9 Mar 2005 07:31:53 -0000 1.1 --- test_paramflags.py 9 Mar 2005 07:37:36 -0000 1.2 *************** *** 110,115 **** # the COM idl of this function would be: ! # int TwoOutArgs([in] int a, [out] int *p1, [in] int b, [out] int *p2); ! proto = CFUNCTYPE(c_int, c_int, POINTER(c_int), c_int, POINTER(c_int)) func = proto("TwoOutArgs", dll, ((1, "a"), (2, "p1"), (1, "b"), (2, "p2"))) self.failUnlessEqual((1, 2), func(1, 2)) --- 110,115 ---- # the COM idl of this function would be: ! # void TwoOutArgs([in] int a, [out] int *p1, [in] int b, [out] int *p2); ! proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) func = proto("TwoOutArgs", dll, ((1, "a"), (2, "p1"), (1, "b"), (2, "p2"))) self.failUnlessEqual((1, 2), func(1, 2)) *************** *** 121,125 **** # this is not yet implemented ! proto = CFUNCTYPE(c_int, c_int, POINTER(c_int), c_int, POINTER(c_int)) self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, --- 121,125 ---- # this is not yet implemented ! proto = CFUNCTYPE(None, c_int, POINTER(c_int), c_int, POINTER(c_int)) self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, |
From: Thomas H. <th...@us...> - 2005-03-09 07:32:03
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20217 Added Files: test_paramflags.py Log Message: Tests for the parameter flags support. --- NEW FILE: test_paramflags.py --- import unittest, os from ctypes import * class RECT(Structure): _fields_ = [("left", c_long), ("top", c_long), ("right", c_long), ("bottom", c_long)] def __repr__(self): return "<RECT(%d, %d, %d, %d) at %x>" % (self.left, self.top, self.right, self.bottom, id(self)) class BOOL(c_long): def check_retval(self, val): if val == 0: raise WinError() _check_retval_ = classmethod(check_retval) class Test(unittest.TestCase): def test_invalid_paramflags(self): import _ctypes_test dll = CDLL(_ctypes_test.__file__) proto = CFUNCTYPE(c_int, POINTER(c_int)) # Hm, I should look into doctest's unittest integration. # Doctest makes it easy to check for actual error messages. # ValueError: paramflags must have the same length as argtypes self.failUnlessRaises(ValueError, lambda: proto("TwoOutArgs", dll, ())) # TypeError: paramflags must be a sequence of (int [,string [,value]]) tuples self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, ((1, 2, 3),))) proto = CFUNCTYPE(c_int, c_int) # TypeError: output parameter 1 not a pointer type: c_long self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, ((2,),))) def test_usage_sample(self): import _ctypes_test dll = CDLL(_ctypes_test.__file__) hwnd_desktop = dll.my_GetDesktopWindow() proto = CFUNCTYPE(BOOL, c_long, POINTER(RECT)) func = proto("my_GetWindowRect", dll, ((1, "hwnd"), (2,))) # returns a RECT instance... self.assertEqual(type(func(hwnd_desktop)), RECT) # ...unless the call fails self.assertRaises(WindowsError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) # TypeError: call takes exactly 1 arguments (3 given) self.assertRaises(TypeError, lambda: func(0, 1, 2)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func(spam=hwnd_desktop)) # TypeError: call takes exactly 1 arguments (2 given) self.assertRaises(TypeError, lambda: func(hwnd=hwnd_desktop, spam=32)) if os.name == "nt": def test_usage_sample_WIN32(self): hwnd_desktop = windll.user32.GetDesktopWindow() proto = WINFUNCTYPE(BOOL, c_long, POINTER(RECT)) func = proto("GetWindowRect", windll.user32, ((1, "hwnd"), (2,))) # returns a RECT instance... self.assertEqual(type(func(hwnd_desktop)), RECT) # returns a RECT instance... self.assertEqual(type(func(hwnd=hwnd_desktop)), RECT) # ...unless the call fails self.assertRaises(WindowsError, lambda: func(0)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func()) # TypeError: call takes exactly 1 arguments (3 given) self.assertRaises(TypeError, lambda: func(0, 1, 2)) # TypeError: required argument 'hwnd' missing self.assertRaises(TypeError, lambda: func(spam=hwnd_desktop)) # TypeError: call takes exactly 1 arguments (2 given) self.assertRaises(TypeError, lambda: func(hwnd=hwnd_desktop, spam=32)) def test_default_args(self): windll.kernel32.GetModuleHandleW proto = WINFUNCTYPE(c_long, c_wchar_p) func = proto("GetModuleHandleW", windll.kernel32, ((1, "lpModuleName", None),)) func(lpModuleName="kernel32") func("kernel32") func(None) func() # XXX Problem with error messages here. # Since the arguments are only counted, # this is the error you will get: # TypeError: call takes exactly 0 arguments (1 given) #func(a=1) def test_multiple_outargs(self): import _ctypes_test dll = CDLL(_ctypes_test.__file__) # the COM idl of this function would be: # int TwoOutArgs([in] int a, [out] int *p1, [in] int b, [out] int *p2); proto = CFUNCTYPE(c_int, c_int, POINTER(c_int), c_int, POINTER(c_int)) func = proto("TwoOutArgs", dll, ((1, "a"), (2, "p1"), (1, "b"), (2, "p2"))) self.failUnlessEqual((1, 2), func(1, 2)) self.failUnlessEqual((1, 2), func(b=2, a=1)) def test_inout_args(self): import _ctypes_test dll = CDLL(_ctypes_test.__file__) # this is not yet implemented proto = CFUNCTYPE(c_int, c_int, POINTER(c_int), c_int, POINTER(c_int)) self.failUnlessRaises(TypeError, lambda: proto("TwoOutArgs", dll, ((1, "a"), (3, "p1"), (1, "b"), (2, "p2")))) if __name__ == "__main__": unittest.main() |
From: Thomas H. <th...@us...> - 2005-03-09 07:30:48
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19992 Modified Files: _ctypes.c Log Message: Support parameter flags. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.214 retrieving revision 1.215 diff -C2 -d -r1.214 -r1.215 *** _ctypes.c 8 Mar 2005 07:56:15 -0000 1.214 --- _ctypes.c 9 Mar 2005 07:30:38 -0000 1.215 *************** *** 2278,2281 **** --- 2278,2333 ---- #endif + /* Returns 1 on success, 0 on error */ + static int + _validate_paramflags(PyTypeObject *type, PyObject *paramflags) + { + int i, len; + StgDictObject *dict = PyType_stgdict((PyObject *)type); + PyObject *argtypes = dict->argtypes; + + if (paramflags == NULL || dict->argtypes == NULL) + return 1; + + len = PyTuple_GET_SIZE(paramflags); + if (len != PyTuple_GET_SIZE(dict->argtypes)) { + PyErr_SetString(PyExc_ValueError, + "paramflags must have the same length as argtypes"); + return 0; + } + + for (i = 0; i < len; ++i) { + PyObject *item = PyTuple_GET_ITEM(paramflags, i); + int flag; + char *name; + PyObject *defval; + PyObject *typ; + if (!PyArg_ParseTuple(item, "i|sO", &flag, &name, &defval)) { + PyErr_SetString(PyExc_TypeError, + "paramflags must be a sequence of (int [,string [,value]]) tuples"); + return 0; + } + typ = PyTuple_GET_ITEM(argtypes, i); + dict = PyType_stgdict(typ); + if ((flag & 2) && (dict->ffi_type.type != FFI_TYPE_POINTER)) { + PyErr_Format(PyExc_TypeError, + "output parameter %d not a pointer type: %s", + i+1, + ((PyTypeObject *)typ)->tp_name); + return 0; + } + switch (flag) { + case PARAMFLAG_FIN: + case PARAMFLAG_FOUT: + break; + default: + PyErr_Format(PyExc_TypeError, + "paramflag value %d not supported", + flag); + return 0; + } + } + return 1; + } + static PyObject * CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) *************** *** 2325,2328 **** --- 2377,2383 ---- } #endif + if (!_validate_paramflags(type, paramflags)) + return NULL; + self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); if (!self) *************** *** 2331,2334 **** --- 2386,2390 ---- Py_XINCREF(paramflags); self->paramflags = paramflags; + *(void **)self->b_ptr = address; *************** *** 2356,2359 **** --- 2412,2418 ---- return NULL; + if (!_validate_paramflags(type, paramflags)) + return NULL; + self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; *************** *** 2474,2486 **** } static PyObject * ! _build_callargs(CFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds) { #ifdef MS_WIN32 ! if (self->index) ! return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); #endif ! Py_INCREF(inargs); ! return inargs; } --- 2533,2796 ---- } + static PyObject * ! _byref(PyObject *obj) ! { ! PyCArgObject *parg; ! if (!CDataObject_Check(obj)) { ! PyErr_SetString(PyExc_TypeError, ! "expected CData instance"); ! return NULL; ! } ! ! parg = new_CArgObject(); ! if (parg == NULL) ! return NULL; ! ! parg->tag = 'P'; ! parg->pffi_type = &ffi_type_pointer; ! Py_INCREF(obj); ! parg->obj = obj; ! parg->value.p = ((CDataObject *)obj)->b_ptr; ! return (PyObject *)parg; ! } ! ! static PyObject * ! _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds) ! { ! PyObject *v; ! ! if (*pindex < PyTuple_GET_SIZE(inargs)) { ! v = PyTuple_GET_ITEM(inargs, *pindex); ! ++*pindex; ! Py_INCREF(v); ! return v; ! } ! if (kwds && (v = PyDict_GetItemString(kwds, name))) { ! ++*pindex; ! Py_INCREF(v); ! return v; ! } ! if (defval) { ! Py_INCREF(defval); ! return defval; ! } ! PyErr_Format(PyExc_TypeError, ! "required argument '%s' missing", name); ! return NULL; ! } ! ! /* ! This function implements higher level functionality plus the ability to call ! functions with keyword arguments by looking at parameter flags. parameter ! flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer ! specifying the direction of the data transfer for this parameter - 'in', ! 'out' or 'inout' (zero means the same as 'in'). The second entry is the ! parameter name, and the third is the default value if the parameter is ! missing in the function call. ! ! Note: keyword args not yet implemented! ! ! This function builds a new tuple 'callargs' which contains the parameters to ! use in the call. Items on this tuple are copied from the 'inargs' tuple for ! 'in' parameters, and constructed from the 'argtypes' tuple for 'out' ! parameters. ! ! */ ! static PyObject * ! _build_callargs(CFuncPtrObject *self, PyObject *argtypes, ! PyObject *inargs, PyObject *kwds, ! PyObject **pretval) { + PyObject *paramflags = self->paramflags; + PyObject *callargs; + StgDictObject *dict; + int i, len; + int inargs_index = 0; + int outmask = 0; + /* It's a little bit difficult to determine how many arguments the + function call requires/accepts. For simplicity, we count the consumed + args and compare this to the number of supplied args. */ + int actual_args; + + *pretval = NULL; + /* Trivial cases, where we either return inargs itself, or a slice of it. */ + if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) { #ifdef MS_WIN32 ! if (self->index) ! return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); #endif ! Py_INCREF(inargs); ! return inargs; ! } ! ! len = PyTuple_GET_SIZE(argtypes); ! callargs = PyTuple_New(len); /* the argument tuple we build */ ! if (callargs == NULL) ! return NULL; ! ! #ifdef MS_WIN32 ! /* For a COM method, skip the first arg */ ! if (self->index) { ! inargs_index = 1; ! } ! #endif ! ! for (i = 0; i < len; ++i) { ! PyObject *item = PyTuple_GET_ITEM(paramflags, i); ! PyObject *ob; ! int flag; ! char *name = NULL; ! PyObject *defval = NULL; ! if (!PyArg_ParseTuple(item, "i|sO", &flag, &name, &defval)) { ! /* Hm. Either we should raise a more specific error ! here, or we should validate the paramflags tuple ! when it is set */ ! _AddTraceback("_build_callargs", __FILE__, __LINE__-4); ! goto error; ! } ! switch (flag) { ! case 0: ! case PARAMFLAG_FIN: ! /* 'in' parameter. Copy it from inargs. */ ! ob =_get_arg(&inargs_index, name, defval, inargs, kwds); ! if (ob == NULL) ! goto error; ! PyTuple_SET_ITEM(callargs, i, ob); ! break; ! case PARAMFLAG_FOUT: ! /* 'out' parameter. ! It's argtypes must be a POINTER of a c type. ! */ ! ob = PyTuple_GET_ITEM(argtypes, i); ! dict = PyType_stgdict(ob); ! /* Create an instance of the pointed-to type */ ! ob = PyObject_CallObject(dict->proto, NULL); ! /* Insert as byref parameter */ ! PyTuple_SET_ITEM(callargs, i, _byref(ob)); ! outmask |= (1 << i); ! break; ! case (PARAMFLAG_FIN | PARAMFLAG_FOUT): ! /* for [in, out] parameters, we should probably ! - call _get_arg to get the [in] value ! - create an object with the [in] value as parameter ! - and then proceed in the same way as for an [out] parameter ! */ ! default: ! PyErr_Format(PyExc_ValueError, ! "paramflag %d not yet implemented", flag); ! goto error; ! break; ! } ! } ! ! /* We have counted the arguments we have consumed in 'inargs_index'. This ! must be the same as len(inargs) + len(kwds), otherwise we have ! either too much or not enough arguments. */ ! ! actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0); ! if (actual_args != inargs_index) { ! /* When we have default values or named parameters, this error ! message is misleading. See unittests/test_paramflags.py ! */ ! PyErr_Format(PyExc_TypeError, ! "call takes exactly %d arguments (%d given)", ! inargs_index, actual_args); ! goto error; ! } ! ! /* outmask is a bitmask containing indexes into callargs. Items at ! these indexes contain values to return. ! */ ! ! len = 0; ! for (i = 0; i < 32; ++i) { ! if (outmask & (1 << i)) ! ++len; ! } ! ! switch (len) { ! int j; ! case 0: ! *pretval = NULL; ! break; ! case 1: ! for (i = 0; i < 32; ++i) { ! if (outmask & (1 << i)) { ! *pretval = PyTuple_GET_ITEM(callargs, i); ! Py_INCREF(*pretval); ! break; ! } ! } ! break; ! default: ! *pretval = PyTuple_New(len); ! j = 0; ! for (i = 0; i < 32; ++i) { ! PyObject *ob; ! if (outmask & (1 << i)) { ! ob = PyTuple_GET_ITEM(callargs, i); ! Py_INCREF(ob); ! PyTuple_SET_ITEM(*pretval, j, ob); ! ++j; ! } ! } ! } ! ! return callargs; ! error: ! Py_DECREF(callargs); ! return NULL; ! } ! ! /* ! For simple objects like c_int and friends, call dict->getfunc. ! Otherwise, return object itself. ! ! Hm, it's not that simple: For a VARIANT, we would like .value as well. ! */ ! static PyObject * ! _get_one(PyObject *obj) ! { ! PyCArgObject *arg = (PyCArgObject *)obj; ! PyObject *result = arg->obj; ! StgDictObject *dict = PyObject_stgdict(result); ! ! if (dict->getfunc) { ! CDataObject *c = (CDataObject *)result; ! return dict->getfunc(c->b_ptr, c->b_size); ! } ! Py_INCREF(result); ! return result; ! } ! ! static PyObject * ! _build_result(PyObject *result, PyObject *retval) ! { ! int i, len; ! ! if (retval == NULL) ! return result; ! if (result == NULL) { ! Py_DECREF(retval); ! return NULL; ! } ! Py_DECREF(result); ! ! if (!PyTuple_CheckExact(retval)) { ! PyObject *v = _get_one(retval); ! Py_DECREF(retval); ! return v; ! } ! assert (retval->ob_refcnt == 1); ! /* We know we are sole owner of the retval tuple. So, we can replace ! the values in it instead of allocating a new one. ! */ ! len = PyTuple_GET_SIZE(retval); ! for (i = 0; i < len; ++i) { ! PyObject *ob = _get_one(PyTuple_GET_ITEM(retval, i)); ! PyTuple_SetItem(retval, i, ob); ! } ! return retval; } *************** *** 2495,2498 **** --- 2805,2809 ---- PyObject *result; PyObject *callargs; + PyObject *retval; #ifdef MS_WIN32 IUnknown *piunk = NULL; *************** *** 2521,2525 **** return NULL; } ! /* there should be more checks? No, in Python*/ /* First arg is an pointer to an interface instance */ if (!this->b_ptr || *(void **)this->b_ptr == NULL) { --- 2832,2836 ---- return NULL; } ! /* there should be more checks? No, in Python */ /* First arg is an pointer to an interface instance */ if (!this->b_ptr || *(void **)this->b_ptr == NULL) { *************** *** 2539,2543 **** } #endif ! callargs = _build_callargs(self, argtypes, inargs, kwds); if (callargs == NULL) return NULL; --- 2850,2854 ---- } #endif ! callargs = _build_callargs(self, argtypes, inargs, kwds, &retval); if (callargs == NULL) return NULL; *************** *** 2583,2587 **** checker); Py_DECREF(callargs); ! return result; } --- 2894,2898 ---- checker); Py_DECREF(callargs); ! return _build_result(result, retval); } |
From: Thomas H. <th...@us...> - 2005-03-09 07:28:46
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19539 Modified Files: _ctypes_test.c Log Message: More test functions for testing parameter flags. Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** _ctypes_test.c 16 Feb 2005 13:17:32 -0000 1.42 --- _ctypes_test.c 9 Mar 2005 07:28:37 -0000 1.43 *************** *** 475,478 **** --- 475,502 ---- } + EXPORT(HWND) my_GetDesktopWindow(void) + { + #ifdef MS_WIN32 + return GetDesktopWindow(); + #else + return 42; + #endif + } + + EXPORT(int) my_GetWindowRect(HWND hwnd, RECT *prect) + { + #ifdef MS_WIN32 + return GetWindowRect(hwnd, prect); + #else + return hwnd == 0; + #endif + } + + EXPORT(int) TwoOutArgs(int a, int *pi, int b, int *pj) + { + *pi = a; + *pj = b; + } + #ifdef MS_WIN32 EXPORT(S2H) __stdcall s_ret_2h_func(S2H inp) { return ret_2h_func(inp); } |
From: Thomas H. <th...@us...> - 2005-03-09 07:28:21
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19503 Modified Files: setup.py Log Message: More test functions for testing parameter flags. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.113 retrieving revision 1.114 diff -C2 -d -r1.113 -r1.114 *** setup.py 7 Mar 2005 09:22:12 -0000 1.113 --- setup.py 9 Mar 2005 07:28:12 -0000 1.114 *************** *** 337,341 **** **kw), Extension("_ctypes_test", ! libraries=["oleaut32"], sources=["source/_ctypes_test.c"], include_dirs=["source/libffi_msvc"], --- 337,341 ---- **kw), Extension("_ctypes_test", ! libraries=["oleaut32", "user32"], sources=["source/_ctypes_test.c"], include_dirs=["source/libffi_msvc"], |
From: Thomas H. <th...@us...> - 2005-03-08 07:56:28
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11327 Modified Files: ctypes.h _ctypes.c Log Message: Allow an optional third parameter 'paramflags' in WINFUNCTYPE and CFUNCTYPE construction calls. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** ctypes.h 10 Feb 2005 09:10:59 -0000 1.69 --- ctypes.h 8 Mar 2005 07:56:15 -0000 1.70 *************** *** 59,62 **** --- 59,63 ---- #ifdef MS_WIN32 int index; + PyObject *paramflags; #endif } CFuncPtrObject; Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.213 retrieving revision 1.214 diff -C2 -d -r1.213 -r1.214 *** _ctypes.c 7 Mar 2005 17:51:28 -0000 1.213 --- _ctypes.c 8 Mar 2005 07:56:15 -0000 1.214 *************** *** 2287,2292 **** CFuncPtrObject *self; void *handle; ! if (!PyArg_ParseTuple(args, "sO", &name, &dll)) return NULL; --- 2287,2293 ---- CFuncPtrObject *self; void *handle; + PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "sO|O!", &name, &dll, &PyTuple_Type, ¶mflags)) return NULL; *************** *** 2328,2331 **** --- 2329,2334 ---- return NULL; + Py_XINCREF(paramflags); + self->paramflags = paramflags; *(void **)self->b_ptr = address; *************** *** 2348,2357 **** int index; char *name = NULL; ! if (!PyArg_ParseTuple(args, "is", &index, &name)) return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; return (PyObject *)self; } --- 2351,2363 ---- int index; char *name = NULL; + PyObject *paramflags = NULL; ! if (!PyArg_ParseTuple(args, "is|O!", &index, &name, &PyTuple_Type, ¶mflags)) return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; + Py_XINCREF(paramflags); + self->paramflags = paramflags; return (PyObject *)self; } *************** *** 2362,2370 **** _basespec_ keyword arg: "i" - function address - "sO" - function name, dll object (with an integer handle) - "is" - vtable index, method name, creates callable calling COM vtbl - "isO" - vtable index, method name, class, creates unbound method calling COM vtbl "O" - must be a callable, creates a C callable function */ static PyObject * --- 2368,2378 ---- _basespec_ keyword arg: + one argument form "i" - function address "O" - must be a callable, creates a C callable function + + two or more argument forms (the third argument is a paramflags tuple) + "sO|O" - function name, dll object (with an integer handle) + "is|O" - vtable index, method name, creates callable calling COM vtbl */ static PyObject * *************** *** 2587,2590 **** --- 2595,2599 ---- Py_VISIT(self->converters); Py_VISIT(self->b_objects); + Py_VISIT(self->paramflags); return 0; } *************** *** 2599,2602 **** --- 2608,2612 ---- Py_CLEAR(self->converters); Py_CLEAR(self->b_objects); + Py_CLEAR(self->paramflags); if (self->b_needsfree) |
From: Thomas H. <th...@us...> - 2005-03-07 17:51:38
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30085 Modified Files: _ctypes.c Log Message: Fixes for linux. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.212 retrieving revision 1.213 diff -C2 -d -r1.212 -r1.213 *** _ctypes.c 7 Mar 2005 17:34:16 -0000 1.212 --- _ctypes.c 7 Mar 2005 17:51:28 -0000 1.213 *************** *** 2469,2474 **** --- 2469,2476 ---- _build_callargs(CFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds) { + #ifdef MS_WIN32 if (self->index) return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); + #endif Py_INCREF(inargs); return inargs; *************** *** 2487,2492 **** #ifdef MS_WIN32 IUnknown *piunk = NULL; - void *pProc; #endif assert(dict); /* if not, it's a bug */ --- 2489,2494 ---- #ifdef MS_WIN32 IUnknown *piunk = NULL; #endif + void *pProc = NULL; assert(dict); /* if not, it's a bug */ *************** *** 3171,3175 **** { PyObject *value = NULL; - int len = PyTuple_GET_SIZE(args); /* XXX Optimize. PyArg_ParseTuple is slow... */ --- 3173,3176 ---- |
From: Thomas H. <th...@us...> - 2005-03-07 17:34:29
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25907 Modified Files: _ctypes.c Log Message: Use the Py_CLEAR macros in the CFuncPtr_clear function. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.211 retrieving revision 1.212 diff -C2 -d -r1.211 -r1.212 *** _ctypes.c 7 Mar 2005 17:29:22 -0000 1.211 --- _ctypes.c 7 Mar 2005 17:34:16 -0000 1.212 *************** *** 2591,2608 **** CFuncPtr_clear(CFuncPtrObject *self) { ! Py_XDECREF(self->callable); ! self->callable = NULL; ! ! Py_XDECREF(self->restype); ! self->restype = NULL; ! ! Py_XDECREF(self->checker); ! self->checker = NULL; ! ! Py_XDECREF(self->argtypes); ! self->argtypes = NULL; ! ! Py_XDECREF(self->converters); ! self->converters = NULL; if (self->b_needsfree) --- 2591,2600 ---- CFuncPtr_clear(CFuncPtrObject *self) { ! Py_CLEAR(self->callable); ! Py_CLEAR(self->restype); ! Py_CLEAR(self->checker); ! Py_CLEAR(self->argtypes); ! Py_CLEAR(self->converters); ! Py_CLEAR(self->b_objects); if (self->b_needsfree) *************** *** 2614,2620 **** self->thunk = NULL; - Py_XDECREF(self->b_objects); - self->b_objects = NULL; - return 0; } --- 2606,2609 ---- |
From: Thomas H. <th...@us...> - 2005-03-07 17:29:35
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24058 Modified Files: _ctypes.c Log Message: Refactoring. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.210 retrieving revision 1.211 diff -C2 -d -r1.210 -r1.211 *** _ctypes.c 7 Mar 2005 09:26:36 -0000 1.210 --- _ctypes.c 7 Mar 2005 17:29:22 -0000 1.211 *************** *** 2026,2030 **** /* If KeepRef fails, we are stumped. The dst memory block has already been changed */ ! return KeepRef(mem, index, result); } --- 2026,2031 ---- /* If KeepRef fails, we are stumped. The dst memory block has already been changed */ ! return KeepRef(mem, index, result); ! } *************** *** 2350,2354 **** if (!PyArg_ParseTuple(args, "is", &index, &name)) return NULL; ! self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; --- 2351,2355 ---- if (!PyArg_ParseTuple(args, "is", &index, &name)) return NULL; ! self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; *************** *** 2466,2475 **** static PyObject * ! CFuncPtr_call(CFuncPtrObject *self, PyObject *args, PyObject *kwds) { PyObject *restype; PyObject *converters; PyObject *checker; StgDictObject *dict = PyObject_stgdict((PyObject *)self); #ifdef MS_WIN32 IUnknown *piunk = NULL; --- 2467,2488 ---- static PyObject * ! _build_callargs(CFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds) ! { ! if (self->index) ! return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); ! Py_INCREF(inargs); ! return inargs; ! } ! ! static PyObject * ! CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds) { PyObject *restype; PyObject *converters; PyObject *checker; + PyObject *argtypes; StgDictObject *dict = PyObject_stgdict((PyObject *)self); + PyObject *result; + PyObject *callargs; #ifdef MS_WIN32 IUnknown *piunk = NULL; *************** *** 2481,2484 **** --- 2494,2498 ---- converters = self->converters ? self->converters : dict->converters; checker = self->checker ? self->checker : dict->checker; + argtypes = self->argtypes ? self->argtypes : dict->argtypes; #ifdef MS_WIN32 *************** *** 2486,2490 **** /* It's a COM method */ CDataObject *this; ! this = (CDataObject *)PyTuple_GetItem(args, 0); /* borrowed ref! */ if (!this) { PyErr_SetString(PyExc_ValueError, --- 2500,2504 ---- /* It's a COM method */ CDataObject *this; ! this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */ if (!this) { PyErr_SetString(PyExc_ValueError, *************** *** 2511,2524 **** } pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000]; } #endif if (converters) { int required = PyTuple_GET_SIZE(converters); ! int actual = PyTuple_GET_SIZE(args); ! #ifdef MS_WIN32 ! if (piunk) ! required ++; ! #endif if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) { /* For cdecl functions, we allow more actual arguments --- 2525,2540 ---- } pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000]; + } else { + pProc = *(void **)self->b_ptr; } #endif + callargs = _build_callargs(self, argtypes, inargs, kwds); + if (callargs == NULL) + return NULL; if (converters) { int required = PyTuple_GET_SIZE(converters); ! int actual = PyTuple_GET_SIZE(callargs); ! if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) { /* For cdecl functions, we allow more actual arguments *************** *** 2526,2529 **** --- 2542,2546 ---- */ if (required > actual) { + Py_DECREF(callargs); PyErr_Format(PyExc_TypeError, "this function takes at least %d argument%s (%d given)", *************** *** 2534,2537 **** --- 2551,2555 ---- } } else if (required != actual) { + Py_DECREF(callargs); PyErr_Format(PyExc_TypeError, "this function takes %d argument%s (%d given)", *************** *** 2542,2567 **** } } #ifdef MS_WIN32 ! if (piunk) { ! PyObject *a = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); ! PyObject *result; ! result = _CallProc(pProc, ! a, ! piunk, ! dict->flags, ! converters, ! restype, ! checker); ! Py_DECREF(a); ! return result; ! } #endif ! return _CallProc(*(void **)self->b_ptr, ! args, ! NULL, ! dict->flags, ! converters, ! restype, ! checker); } --- 2560,2577 ---- } } + + result = _CallProc(pProc, + callargs, #ifdef MS_WIN32 ! piunk, ! #else ! NULL, #endif ! dict->flags, ! converters, ! restype, ! checker); ! Py_DECREF(callargs); ! return result; } *************** *** 3163,3167 **** if (!result) return -1; ! /* consumes the refcount the setfunc returns */ return KeepRef(self, 0, result); --- 3173,3177 ---- if (!result) return -1; ! /* consumes the refcount the setfunc returns */ return KeepRef(self, 0, result); *************** *** 3172,3176 **** { PyObject *value = NULL; ! /* XXX Optimize. PyArg_ParseTuple is slow... */ if (!PyArg_ParseTuple(args, "|O", &value)) --- 3182,3187 ---- { PyObject *value = NULL; ! int len = PyTuple_GET_SIZE(args); ! /* XXX Optimize. PyArg_ParseTuple is slow... */ if (!PyArg_ParseTuple(args, "|O", &value)) |
From: Thomas H. <th...@us...> - 2005-03-07 09:26:53
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4130 Modified Files: _ctypes.c Log Message: WINFUNCTYPE no longer accepts the third argument which creates an unbound method. It's more flexible to explicitely call new.instancemethod to create one. Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.209 retrieving revision 1.210 diff -C2 -d -r1.209 -r1.210 *** _ctypes.c 4 Mar 2005 09:25:29 -0000 1.209 --- _ctypes.c 7 Mar 2005 09:26:36 -0000 1.210 *************** *** 2347,2360 **** int index; char *name = NULL; - PyObject *cls = NULL; ! if (!PyArg_ParseTuple(args, "is|O", &index, &name, &cls)) return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); - self->index = index + 0x1000; - if (cls) - return PyMethod_New((PyObject *)self, NULL, cls); return (PyObject *)self; } --- 2347,2356 ---- int index; char *name = NULL; ! if (!PyArg_ParseTuple(args, "is", &index, &name)) return NULL; self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); self->index = index + 0x1000; return (PyObject *)self; } |
From: Thomas H. <th...@us...> - 2005-03-07 09:26:22
|
Update of /cvsroot/ctypes/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4061 Modified Files: __init__.py Log Message: WINFUNCTYPE no longer accepts the third argument which creates an unbound method. It's more flexible to explicitely call new.instancemethod to create one. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/ctypes/__init__.py,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** __init__.py 16 Feb 2005 13:17:15 -0000 1.54 --- __init__.py 7 Mar 2005 09:26:12 -0000 1.55 *************** *** 77,81 **** prototype(vtbl_index, method_name) - a function that calls a COM method - prototype(vtbl_index, method_name, class) - an unbound method that calls a COM method prototype(callable) - returns a C callable function that calls callable prototype(funct_name, dll) - a function that calls an exported function in a dll --- 77,80 ---- *************** *** 108,112 **** prototype(vtbl_index, method_name) - a function that calls a COM method - prototype(vtbl_index, method_name, class) - an unbound method that calls a COM method prototype(callable) - returns a C callable function that calls callable prototype(funct_name, dll) - a function that calls an exported function in a dll --- 107,110 ---- |
From: Thomas H. <th...@us...> - 2005-03-07 09:26:06
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3921 Modified Files: __init__.py Log Message: WINFUNCTYPE no longer accepts the third argument which creates an unbound method. It's more flexible to explicitely call new.instancemethod to create one. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** __init__.py 4 Mar 2005 09:39:43 -0000 1.14 --- __init__.py 7 Mar 2005 09:25:37 -0000 1.15 *************** *** 139,145 **** # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! # create a bound method, which will call into the COM vtbl ! # the three-argument call requires ctypes 0.9.3 ! mth = prototype(i + vtbl_offset, name, self) impl = getattr(self, name, None) if impl is None: --- 139,144 ---- # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! mth = prototype(i + vtbl_offset, name) ! mth = new.instancemethod(mth, None, self) impl = getattr(self, name, None) if impl is None: |