Reword paragraph to clarify
[pytest.git] / Modules / _ctypes / _ctypes.c
blobd26ad1d3e26113ff0dbfbdf3fff3b0892760b7e7
1 /*****************************************************************
2 This file should be kept compatible with Python 2.3, see PEP 291.
3 *****************************************************************/
6 /*
7 ToDo:
9 Get rid of the checker (and also the converters) field in CFuncPtrObject and
10 StgDictObject, and replace them by slot functions in StgDictObject.
12 think about a buffer-like object (memory? bytes?)
14 Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
15 What about c_char and c_wchar arrays then?
17 Add from_mmap, from_file, from_string metaclass methods.
19 Maybe we can get away with from_file (calls read) and with a from_buffer
20 method?
22 And what about the to_mmap, to_file, to_str(?) methods? They would clobber
23 the namespace, probably. So, functions instead? And we already have memmove...
28 Name methods, members, getsets
29 ==============================================================================
31 StructType_Type __new__(), from_address(), __mul__(), from_param()
32 UnionType_Type __new__(), from_address(), __mul__(), from_param()
33 PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type()
34 ArrayType_Type __new__(), from_address(), __mul__(), from_param()
35 SimpleType_Type __new__(), from_address(), __mul__(), from_param()
37 CData_Type
38 Struct_Type __new__(), __init__()
39 Pointer_Type __new__(), __init__(), _as_parameter_, contents
40 Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
41 Simple_Type __new__(), __init__(), _as_parameter_
43 CField_Type
44 StgDict_Type
46 ==============================================================================
48 class methods
49 -------------
51 It has some similarity to the byref() construct compared to pointer()
52 from_address(addr)
53 - construct an instance from a given memory block (sharing this memory block)
55 from_param(obj)
56 - typecheck and convert a Python object into a C function call parameter
57 the result may be an instance of the type, or an integer or tuple
58 (typecode, value[, obj])
60 instance methods/properties
61 ---------------------------
63 _as_parameter_
64 - convert self into a C function call parameter
65 This is either an integer, or a 3-tuple (typecode, value, obj)
67 functions
68 ---------
70 sizeof(cdata)
71 - return the number of bytes the buffer contains
73 sizeof(ctype)
74 - return the number of bytes the buffer of an instance would contain
76 byref(cdata)
78 addressof(cdata)
80 pointer(cdata)
82 POINTER(ctype)
84 bytes(cdata)
85 - return the buffer contents as a sequence of bytes (which is currently a string)
90 * StgDict_Type
91 * StructType_Type
92 * UnionType_Type
93 * PointerType_Type
94 * ArrayType_Type
95 * SimpleType_Type
97 * CData_Type
98 * Struct_Type
99 * Union_Type
100 * Array_Type
101 * Simple_Type
102 * Pointer_Type
103 * CField_Type
107 #include "Python.h"
108 #include "structmember.h"
110 #include <ffi.h>
111 #ifdef MS_WIN32
112 #include <windows.h>
113 #include <malloc.h>
114 #ifndef IS_INTRESOURCE
115 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
116 #endif
117 # ifdef _WIN32_WCE
118 /* Unlike desktop Windows, WinCE has both W and A variants of
119 GetProcAddress, but the default W version is not what we want */
120 # undef GetProcAddress
121 # define GetProcAddress GetProcAddressA
122 # endif
123 #else
124 #include "ctypes_dlfcn.h"
125 #endif
126 #include "ctypes.h"
128 PyObject *PyExc_ArgError;
129 static PyTypeObject Simple_Type;
131 char *conversion_mode_encoding = NULL;
132 char *conversion_mode_errors = NULL;
135 /******************************************************************/
137 StructType_Type - a meta type/class. Creating a new class using this one as
138 __metaclass__ will call the contructor StructUnionType_new. It replaces the
139 tp_dict member with a new instance of StgDict, and initializes the C
140 accessible fields somehow.
143 static PyObject *
144 StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isStruct)
146 PyTypeObject *result;
147 PyObject *fields;
148 StgDictObject *dict;
150 /* create the new instance (which is a class,
151 since we are a metatype!) */
152 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
153 if (!result)
154 return NULL;
156 /* keep this for bw compatibility */
157 if (PyDict_GetItemString(result->tp_dict, "_abstract_"))
158 return (PyObject *)result;
160 dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL);
161 if (!dict) {
162 Py_DECREF(result);
163 return NULL;
165 /* replace the class dict by our updated stgdict, which holds info
166 about storage requirements of the instances */
167 if (-1 == PyDict_Update((PyObject *)dict, result->tp_dict)) {
168 Py_DECREF(result);
169 Py_DECREF((PyObject *)dict);
170 return NULL;
172 Py_DECREF(result->tp_dict);
173 result->tp_dict = (PyObject *)dict;
175 fields = PyDict_GetItemString((PyObject *)dict, "_fields_");
176 if (!fields) {
177 StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
179 if (basedict == NULL)
180 return (PyObject *)result;
181 /* copy base dict */
182 if (-1 == StgDict_clone(dict, basedict)) {
183 Py_DECREF(result);
184 return NULL;
186 dict->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass dict */
187 basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
188 return (PyObject *)result;
191 if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
192 Py_DECREF(result);
193 return NULL;
195 return (PyObject *)result;
198 static PyObject *
199 StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
201 return StructUnionType_new(type, args, kwds, 1);
204 static PyObject *
205 UnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
207 return StructUnionType_new(type, args, kwds, 0);
210 static char from_address_doc[] =
211 "C.from_address(integer) -> C instance\naccess a C instance at the specified address";
213 static PyObject *
214 CDataType_from_address(PyObject *type, PyObject *value)
216 void *buf;
217 if (!PyInt_Check(value) && !PyLong_Check(value)) {
218 PyErr_SetString(PyExc_TypeError,
219 "integer expected");
220 return NULL;
222 buf = (void *)PyLong_AsVoidPtr(value);
223 if (PyErr_Occurred())
224 return NULL;
225 return CData_AtAddress(type, buf);
228 static char in_dll_doc[] =
229 "C.in_dll(dll, name) -> C instance\naccess a C instance in a dll";
231 static PyObject *
232 CDataType_in_dll(PyObject *type, PyObject *args)
234 PyObject *dll;
235 char *name;
236 PyObject *obj;
237 void *handle;
238 void *address;
240 if (!PyArg_ParseTuple(args, "Os:in_dll", &dll, &name))
241 return NULL;
243 obj = PyObject_GetAttrString(dll, "_handle");
244 if (!obj)
245 return NULL;
246 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
247 PyErr_SetString(PyExc_TypeError,
248 "the _handle attribute of the second argument must be an integer");
249 Py_DECREF(obj);
250 return NULL;
252 handle = (void *)PyLong_AsVoidPtr(obj);
253 Py_DECREF(obj);
254 if (PyErr_Occurred()) {
255 PyErr_SetString(PyExc_ValueError,
256 "could not convert the _handle attribute to a pointer");
257 return NULL;
260 #ifdef MS_WIN32
261 address = (void *)GetProcAddress(handle, name);
262 if (!address) {
263 PyErr_Format(PyExc_ValueError,
264 "symbol '%s' not found",
265 name);
266 return NULL;
268 #else
269 address = (void *)ctypes_dlsym(handle, name);
270 if (!address) {
271 PyErr_Format(PyExc_ValueError,
272 #ifdef __CYGWIN__
273 /* dlerror() isn't very helpful on cygwin */
274 "symbol '%s' not found (%s) ",
275 name,
276 #endif
277 ctypes_dlerror());
278 return NULL;
280 #endif
281 return CData_AtAddress(type, address);
284 static char from_param_doc[] =
285 "Convert a Python object into a function call parameter.";
287 static PyObject *
288 CDataType_from_param(PyObject *type, PyObject *value)
290 if (1 == PyObject_IsInstance(value, type)) {
291 Py_INCREF(value);
292 return value;
294 if (PyCArg_CheckExact(value)) {
295 PyCArgObject *p = (PyCArgObject *)value;
296 PyObject *ob = p->obj;
297 const char *ob_name;
298 StgDictObject *dict;
299 dict = PyType_stgdict(type);
301 /* If we got a PyCArgObject, we must check if the object packed in it
302 is an instance of the type's dict->proto */
303 // if(dict && ob && dict->proto == (PyObject *)ob->ob_type){
304 if(dict && ob
305 && PyObject_IsInstance(ob, dict->proto)) {
306 Py_INCREF(value);
307 return value;
309 ob_name = (ob) ? ob->ob_type->tp_name : "???";
310 PyErr_Format(PyExc_TypeError,
311 "expected %s instance instead of pointer to %s",
312 ((PyTypeObject *)type)->tp_name, ob_name);
313 return NULL;
315 #if 1
316 /* XXX Remove this section ??? */
317 /* tuple returned by byref: */
318 /* ('i', addr, obj) */
319 if (PyTuple_Check(value)) {
320 PyObject *ob;
321 StgDictObject *dict;
323 dict = PyType_stgdict(type);
324 ob = PyTuple_GetItem(value, 2);
325 if (dict && ob &&
326 0 == PyObject_IsInstance(value, dict->proto)) {
327 Py_INCREF(value);
328 return value;
331 /* ... and leave the rest */
332 #endif
333 PyErr_Format(PyExc_TypeError,
334 "expected %s instance instead of %s",
335 ((PyTypeObject *)type)->tp_name,
336 value->ob_type->tp_name);
337 return NULL;
340 static PyMethodDef CDataType_methods[] = {
341 { "from_param", CDataType_from_param, METH_O, from_param_doc },
342 { "from_address", CDataType_from_address, METH_O, from_address_doc },
343 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc },
344 { NULL, NULL },
347 static PyObject *
348 CDataType_repeat(PyObject *self, Py_ssize_t length)
350 if (length < 0)
351 return PyErr_Format(PyExc_ValueError,
352 #if (PY_VERSION_HEX < 0x02050000)
353 "Array length must be >= 0, not %d",
354 #else
355 "Array length must be >= 0, not %zd",
356 #endif
357 length);
358 return CreateArrayType(self, length);
361 static PySequenceMethods CDataType_as_sequence = {
362 0, /* inquiry sq_length; */
363 0, /* binaryfunc sq_concat; */
364 CDataType_repeat, /* intargfunc sq_repeat; */
365 0, /* intargfunc sq_item; */
366 0, /* intintargfunc sq_slice; */
367 0, /* intobjargproc sq_ass_item; */
368 0, /* intintobjargproc sq_ass_slice; */
369 0, /* objobjproc sq_contains; */
371 0, /* binaryfunc sq_inplace_concat; */
372 0, /* intargfunc sq_inplace_repeat; */
375 static int
376 CDataType_clear(PyTypeObject *self)
378 StgDictObject *dict = PyType_stgdict((PyObject *)self);
379 if (dict)
380 Py_CLEAR(dict->proto);
381 return PyType_Type.tp_clear((PyObject *)self);
384 static int
385 CDataType_traverse(PyTypeObject *self, visitproc visit, void *arg)
387 StgDictObject *dict = PyType_stgdict((PyObject *)self);
388 if (dict)
389 Py_VISIT(dict->proto);
390 return PyType_Type.tp_traverse((PyObject *)self, visit, arg);
393 static int
394 StructType_setattro(PyObject *self, PyObject *key, PyObject *value)
396 /* XXX Should we disallow deleting _fields_? */
397 if (-1 == PyObject_GenericSetAttr(self, key, value))
398 return -1;
400 if (value && PyString_Check(key) &&
401 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
402 return StructUnionType_update_stgdict(self, value, 1);
403 return 0;
407 static int
408 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
410 /* XXX Should we disallow deleting _fields_? */
411 if (-1 == PyObject_GenericSetAttr(self, key, value))
412 return -1;
414 if (PyString_Check(key) &&
415 0 == strcmp(PyString_AS_STRING(key), "_fields_"))
416 return StructUnionType_update_stgdict(self, value, 0);
417 return 0;
421 PyTypeObject StructType_Type = {
422 PyObject_HEAD_INIT(NULL)
423 0, /* ob_size */
424 "_ctypes.StructType", /* tp_name */
425 0, /* tp_basicsize */
426 0, /* tp_itemsize */
427 0, /* tp_dealloc */
428 0, /* tp_print */
429 0, /* tp_getattr */
430 0, /* tp_setattr */
431 0, /* tp_compare */
432 0, /* tp_repr */
433 0, /* tp_as_number */
434 &CDataType_as_sequence, /* tp_as_sequence */
435 0, /* tp_as_mapping */
436 0, /* tp_hash */
437 0, /* tp_call */
438 0, /* tp_str */
439 0, /* tp_getattro */
440 StructType_setattro, /* tp_setattro */
441 0, /* tp_as_buffer */
442 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
443 "metatype for the CData Objects", /* tp_doc */
444 (traverseproc)CDataType_traverse, /* tp_traverse */
445 (inquiry)CDataType_clear, /* tp_clear */
446 0, /* tp_richcompare */
447 0, /* tp_weaklistoffset */
448 0, /* tp_iter */
449 0, /* tp_iternext */
450 CDataType_methods, /* tp_methods */
451 0, /* tp_members */
452 0, /* tp_getset */
453 0, /* tp_base */
454 0, /* tp_dict */
455 0, /* tp_descr_get */
456 0, /* tp_descr_set */
457 0, /* tp_dictoffset */
458 0, /* tp_init */
459 0, /* tp_alloc */
460 StructType_new, /* tp_new */
461 0, /* tp_free */
464 static PyTypeObject UnionType_Type = {
465 PyObject_HEAD_INIT(NULL)
466 0, /* ob_size */
467 "_ctypes.UnionType", /* tp_name */
468 0, /* tp_basicsize */
469 0, /* tp_itemsize */
470 0, /* tp_dealloc */
471 0, /* tp_print */
472 0, /* tp_getattr */
473 0, /* tp_setattr */
474 0, /* tp_compare */
475 0, /* tp_repr */
476 0, /* tp_as_number */
477 &CDataType_as_sequence, /* tp_as_sequence */
478 0, /* tp_as_mapping */
479 0, /* tp_hash */
480 0, /* tp_call */
481 0, /* tp_str */
482 0, /* tp_getattro */
483 UnionType_setattro, /* tp_setattro */
484 0, /* tp_as_buffer */
485 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
486 "metatype for the CData Objects", /* tp_doc */
487 (traverseproc)CDataType_traverse, /* tp_traverse */
488 (inquiry)CDataType_clear, /* tp_clear */
489 0, /* tp_richcompare */
490 0, /* tp_weaklistoffset */
491 0, /* tp_iter */
492 0, /* tp_iternext */
493 CDataType_methods, /* tp_methods */
494 0, /* tp_members */
495 0, /* tp_getset */
496 0, /* tp_base */
497 0, /* tp_dict */
498 0, /* tp_descr_get */
499 0, /* tp_descr_set */
500 0, /* tp_dictoffset */
501 0, /* tp_init */
502 0, /* tp_alloc */
503 UnionType_new, /* tp_new */
504 0, /* tp_free */
508 /******************************************************************/
512 The PointerType_Type metaclass must ensure that the subclass of Pointer can be
513 created. It must check for a _type_ attribute in the class. Since are no
514 runtime created properties, a CField is probably *not* needed ?
516 class IntPointer(Pointer):
517 _type_ = "i"
519 The Pointer_Type provides the functionality: a contents method/property, a
520 size property/method, and the sequence protocol.
524 static int
525 PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
527 if (!proto || !PyType_Check(proto)) {
528 PyErr_SetString(PyExc_TypeError,
529 "_type_ must be a type");
530 return -1;
532 if (!PyType_stgdict(proto)) {
533 PyErr_SetString(PyExc_TypeError,
534 "_type_ must have storage info");
535 return -1;
537 Py_INCREF(proto);
538 Py_XDECREF(stgdict->proto);
539 stgdict->proto = proto;
540 return 0;
543 static PyObject *
544 PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
546 PyTypeObject *result;
547 StgDictObject *stgdict;
548 PyObject *proto;
549 PyObject *typedict;
551 typedict = PyTuple_GetItem(args, 2);
552 if (!typedict)
553 return NULL;
555 stgdict items size, align, length contain info about pointers itself,
556 stgdict->proto has info about the pointed to type!
558 stgdict = (StgDictObject *)PyObject_CallObject(
559 (PyObject *)&StgDict_Type, NULL);
560 if (!stgdict)
561 return NULL;
562 stgdict->size = sizeof(void *);
563 stgdict->align = getentry("P")->pffi_type->alignment;
564 stgdict->length = 1;
565 stgdict->ffi_type_pointer = ffi_type_pointer;
567 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
568 if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
569 Py_DECREF((PyObject *)stgdict);
570 return NULL;
573 /* create the new instance (which is a class,
574 since we are a metatype!) */
575 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
576 if (result == NULL) {
577 Py_DECREF((PyObject *)stgdict);
578 return NULL;
581 /* replace the class dict by our updated spam dict */
582 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
583 Py_DECREF(result);
584 Py_DECREF((PyObject *)stgdict);
585 return NULL;
587 Py_DECREF(result->tp_dict);
588 result->tp_dict = (PyObject *)stgdict;
590 return (PyObject *)result;
594 static PyObject *
595 PointerType_set_type(PyTypeObject *self, PyObject *type)
597 StgDictObject *dict;
599 dict = PyType_stgdict((PyObject *)self);
600 assert(dict);
602 if (-1 == PointerType_SetProto(dict, type))
603 return NULL;
605 if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type))
606 return NULL;
608 Py_INCREF(Py_None);
609 return Py_None;
612 staticforward PyObject *_byref(PyObject *);
614 static PyObject *
615 PointerType_from_param(PyObject *type, PyObject *value)
617 StgDictObject *typedict;
619 if (value == Py_None)
620 return PyInt_FromLong(0); /* NULL pointer */
622 typedict = PyType_stgdict(type);
624 /* If we expect POINTER(<type>), but receive a <type> instance, accept
625 it by calling byref(<type>).
627 switch (PyObject_IsInstance(value, typedict->proto)) {
628 case 1:
629 Py_INCREF(value); /* _byref steals a refcount */
630 return _byref(value);
631 case -1:
632 PyErr_Clear();
633 break;
634 default:
635 break;
638 if (PointerObject_Check(value) || ArrayObject_Check(value)) {
639 /* Array instances are also pointers when
640 the item types are the same.
642 StgDictObject *v = PyObject_stgdict(value);
643 if (PyObject_IsSubclass(v->proto, typedict->proto)) {
644 Py_INCREF(value);
645 return value;
648 return CDataType_from_param(type, value);
651 static PyMethodDef PointerType_methods[] = {
652 { "from_address", CDataType_from_address, METH_O, from_address_doc },
653 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
654 { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc},
655 { "set_type", (PyCFunction)PointerType_set_type, METH_O },
656 { NULL, NULL },
659 PyTypeObject PointerType_Type = {
660 PyObject_HEAD_INIT(NULL)
661 0, /* ob_size */
662 "_ctypes.PointerType", /* tp_name */
663 0, /* tp_basicsize */
664 0, /* tp_itemsize */
665 0, /* tp_dealloc */
666 0, /* tp_print */
667 0, /* tp_getattr */
668 0, /* tp_setattr */
669 0, /* tp_compare */
670 0, /* tp_repr */
671 0, /* tp_as_number */
672 &CDataType_as_sequence, /* tp_as_sequence */
673 0, /* tp_as_mapping */
674 0, /* tp_hash */
675 0, /* tp_call */
676 0, /* tp_str */
677 0, /* tp_getattro */
678 0, /* tp_setattro */
679 0, /* tp_as_buffer */
680 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
681 "metatype for the Pointer Objects", /* tp_doc */
682 (traverseproc)CDataType_traverse, /* tp_traverse */
683 (inquiry)CDataType_clear, /* tp_clear */
684 0, /* tp_richcompare */
685 0, /* tp_weaklistoffset */
686 0, /* tp_iter */
687 0, /* tp_iternext */
688 PointerType_methods, /* tp_methods */
689 0, /* tp_members */
690 0, /* tp_getset */
691 0, /* tp_base */
692 0, /* tp_dict */
693 0, /* tp_descr_get */
694 0, /* tp_descr_set */
695 0, /* tp_dictoffset */
696 0, /* tp_init */
697 0, /* tp_alloc */
698 PointerType_new, /* tp_new */
699 0, /* tp_free */
703 /******************************************************************/
705 ArrayType_Type
708 ArrayType_new ensures that the new Array subclass created has a _length_
709 attribute, and a _type_ attribute.
712 static int
713 CharArray_set_raw(CDataObject *self, PyObject *value)
715 char *ptr;
716 Py_ssize_t size;
717 if (PyBuffer_Check(value)) {
718 size = value->ob_type->tp_as_buffer->bf_getreadbuffer(value, 0, (void *)&ptr);
719 if (size < 0)
720 return -1;
721 } else if (-1 == PyString_AsStringAndSize(value, &ptr, &size)) {
722 return -1;
724 if (size > self->b_size) {
725 PyErr_SetString(PyExc_ValueError,
726 "string too long");
727 return -1;
730 memcpy(self->b_ptr, ptr, size);
732 return 0;
735 static PyObject *
736 CharArray_get_raw(CDataObject *self)
738 return PyString_FromStringAndSize(self->b_ptr, self->b_size);
741 static PyObject *
742 CharArray_get_value(CDataObject *self)
744 int i;
745 char *ptr = self->b_ptr;
746 for (i = 0; i < self->b_size; ++i)
747 if (*ptr++ == '\0')
748 break;
749 return PyString_FromStringAndSize(self->b_ptr, i);
752 static int
753 CharArray_set_value(CDataObject *self, PyObject *value)
755 char *ptr;
756 int size;
758 if (PyUnicode_Check(value)) {
759 value = PyUnicode_AsEncodedString(value,
760 conversion_mode_encoding,
761 conversion_mode_errors);
762 if (!value)
763 return -1;
764 } else if (!PyString_Check(value)) {
765 PyErr_Format(PyExc_TypeError,
766 "string expected instead of %s instance",
767 value->ob_type->tp_name);
768 return -1;
769 } else
770 Py_INCREF(value);
771 size = PyString_GET_SIZE(value);
772 if (size > self->b_size) {
773 PyErr_SetString(PyExc_ValueError,
774 "string too long");
775 Py_DECREF(value);
776 return -1;
779 ptr = PyString_AS_STRING(value);
780 memcpy(self->b_ptr, ptr, size);
781 if (size < self->b_size)
782 self->b_ptr[size] = '\0';
783 Py_DECREF(value);
785 return 0;
788 static PyGetSetDef CharArray_getsets[] = {
789 { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
790 "value", NULL },
791 { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
792 "string value"},
793 { NULL, NULL }
796 #ifdef CTYPES_UNICODE
797 static PyObject *
798 WCharArray_get_value(CDataObject *self)
800 unsigned int i;
801 wchar_t *ptr = (wchar_t *)self->b_ptr;
802 for (i = 0; i < self->b_size/sizeof(wchar_t); ++i)
803 if (*ptr++ == (wchar_t)0)
804 break;
805 return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
808 static int
809 WCharArray_set_value(CDataObject *self, PyObject *value)
811 int result = 0;
813 if (PyString_Check(value)) {
814 value = PyUnicode_FromEncodedObject(value,
815 conversion_mode_encoding,
816 conversion_mode_errors);
817 if (!value)
818 return -1;
819 } else if (!PyUnicode_Check(value)) {
820 PyErr_Format(PyExc_TypeError,
821 "unicode string expected instead of %s instance",
822 value->ob_type->tp_name);
823 return -1;
824 } else
825 Py_INCREF(value);
826 if ((unsigned)PyUnicode_GET_SIZE(value) > self->b_size/sizeof(wchar_t)) {
827 PyErr_SetString(PyExc_ValueError,
828 "string too long");
829 result = -1;
830 goto done;
832 result = PyUnicode_AsWideChar((PyUnicodeObject *)value,
833 (wchar_t *)self->b_ptr,
834 self->b_size/sizeof(wchar_t));
835 if (result >= 0 && (unsigned)result < self->b_size/sizeof(wchar_t))
836 ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
837 if (result > 0)
838 result = 0;
839 done:
840 Py_DECREF(value);
842 return result;
845 static PyGetSetDef WCharArray_getsets[] = {
846 { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
847 "string value"},
848 { NULL, NULL }
850 #endif
853 The next three functions copied from Python's typeobject.c.
855 They are used to attach methods, members, or getsets to a type *after* it
856 has been created: Arrays of characters have additional getsets to treat them
857 as strings.
860 static int
861 add_methods(PyTypeObject *type, PyMethodDef *meth)
863 PyObject *dict = type->tp_dict;
864 for (; meth->ml_name != NULL; meth++) {
865 PyObject *descr;
866 descr = PyDescr_NewMethod(type, meth);
867 if (descr == NULL)
868 return -1;
869 if (PyDict_SetItemString(dict,meth->ml_name, descr) < 0)
870 return -1;
871 Py_DECREF(descr);
873 return 0;
876 static int
877 add_members(PyTypeObject *type, PyMemberDef *memb)
879 PyObject *dict = type->tp_dict;
880 for (; memb->name != NULL; memb++) {
881 PyObject *descr;
882 descr = PyDescr_NewMember(type, memb);
883 if (descr == NULL)
884 return -1;
885 if (PyDict_SetItemString(dict, memb->name, descr) < 0)
886 return -1;
887 Py_DECREF(descr);
889 return 0;
893 static int
894 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
896 PyObject *dict = type->tp_dict;
897 for (; gsp->name != NULL; gsp++) {
898 PyObject *descr;
899 descr = PyDescr_NewGetSet(type, gsp);
900 if (descr == NULL)
901 return -1;
902 if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
903 return -1;
904 Py_DECREF(descr);
906 return 0;
910 static PyObject *
911 ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
913 PyTypeObject *result;
914 StgDictObject *stgdict;
915 StgDictObject *itemdict;
916 PyObject *proto;
917 PyObject *typedict;
918 int length;
920 int itemsize, itemalign;
922 typedict = PyTuple_GetItem(args, 2);
923 if (!typedict)
924 return NULL;
926 proto = PyDict_GetItemString(typedict, "_length_"); /* Borrowed ref */
927 if (!proto || !PyInt_Check(proto)) {
928 PyErr_SetString(PyExc_AttributeError,
929 "class must define a '_length_' attribute, "
930 "which must be a positive integer");
931 return NULL;
933 length = PyInt_AS_LONG(proto);
935 proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
936 if (!proto) {
937 PyErr_SetString(PyExc_AttributeError,
938 "class must define a '_type_' attribute");
939 return NULL;
942 stgdict = (StgDictObject *)PyObject_CallObject(
943 (PyObject *)&StgDict_Type, NULL);
944 if (!stgdict)
945 return NULL;
947 itemdict = PyType_stgdict(proto);
948 if (!itemdict) {
949 PyErr_SetString(PyExc_TypeError,
950 "_type_ must have storage info");
951 Py_DECREF((PyObject *)stgdict);
952 return NULL;
955 itemsize = itemdict->size;
956 itemalign = itemdict->align;
958 stgdict->size = itemsize * length;
959 stgdict->align = itemalign;
960 stgdict->length = length;
961 Py_INCREF(proto);
962 stgdict->proto = proto;
964 /* Arrays are passed as pointers to function calls. */
965 stgdict->ffi_type_pointer = ffi_type_pointer;
967 /* create the new instance (which is a class,
968 since we are a metatype!) */
969 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
970 if (result == NULL)
971 return NULL;
973 /* replace the class dict by our updated spam dict */
974 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
975 Py_DECREF(result);
976 Py_DECREF((PyObject *)stgdict);
977 return NULL;
979 Py_DECREF(result->tp_dict);
980 result->tp_dict = (PyObject *)stgdict;
982 /* Special case for character arrays.
983 A permanent annoyance: char arrays are also strings!
985 if (itemdict->getfunc == getentry("c")->getfunc) {
986 if (-1 == add_getset(result, CharArray_getsets))
987 return NULL;
988 #ifdef CTYPES_UNICODE
989 } else if (itemdict->getfunc == getentry("u")->getfunc) {
990 if (-1 == add_getset(result, WCharArray_getsets))
991 return NULL;
992 #endif
995 return (PyObject *)result;
998 PyTypeObject ArrayType_Type = {
999 PyObject_HEAD_INIT(NULL)
1000 0, /* ob_size */
1001 "_ctypes.ArrayType", /* tp_name */
1002 0, /* tp_basicsize */
1003 0, /* tp_itemsize */
1004 0, /* tp_dealloc */
1005 0, /* tp_print */
1006 0, /* tp_getattr */
1007 0, /* tp_setattr */
1008 0, /* tp_compare */
1009 0, /* tp_repr */
1010 0, /* tp_as_number */
1011 &CDataType_as_sequence, /* tp_as_sequence */
1012 0, /* tp_as_mapping */
1013 0, /* tp_hash */
1014 0, /* tp_call */
1015 0, /* tp_str */
1016 0, /* tp_getattro */
1017 0, /* tp_setattro */
1018 0, /* tp_as_buffer */
1019 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1020 "metatype for the Array Objects", /* tp_doc */
1021 0, /* tp_traverse */
1022 0, /* tp_clear */
1023 0, /* tp_richcompare */
1024 0, /* tp_weaklistoffset */
1025 0, /* tp_iter */
1026 0, /* tp_iternext */
1027 CDataType_methods, /* tp_methods */
1028 0, /* tp_members */
1029 0, /* tp_getset */
1030 0, /* tp_base */
1031 0, /* tp_dict */
1032 0, /* tp_descr_get */
1033 0, /* tp_descr_set */
1034 0, /* tp_dictoffset */
1035 0, /* tp_init */
1036 0, /* tp_alloc */
1037 ArrayType_new, /* tp_new */
1038 0, /* tp_free */
1042 /******************************************************************/
1044 SimpleType_Type
1048 SimpleType_new ensures that the new Simple_Type subclass created has a valid
1049 _type_ attribute.
1053 static char *SIMPLE_TYPE_CHARS = "cbBhHiIlLdfuzZqQPXOv";
1055 static PyObject *
1056 c_wchar_p_from_param(PyObject *type, PyObject *value)
1058 #if (PYTHON_API_VERSION < 1012)
1059 # error not supported
1060 #endif
1061 if (value == Py_None) {
1062 Py_INCREF(Py_None);
1063 return Py_None;
1065 if (PyUnicode_Check(value) || PyString_Check(value)) {
1066 PyCArgObject *parg;
1067 struct fielddesc *fd = getentry("Z");
1069 parg = new_CArgObject();
1070 parg->pffi_type = &ffi_type_pointer;
1071 parg->tag = 'Z';
1072 parg->obj = fd->setfunc(&parg->value, value, 0);
1073 if (parg->obj == NULL) {
1074 Py_DECREF(parg);
1075 return NULL;
1077 return (PyObject *)parg;
1079 if (PyObject_IsInstance(value, type)) {
1080 Py_INCREF(value);
1081 return value;
1083 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1084 /* c_wchar array instance or pointer(c_wchar(...)) */
1085 StgDictObject *dt = PyObject_stgdict(value);
1086 StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1087 if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1088 Py_INCREF(value);
1089 return value;
1092 if (PyCArg_CheckExact(value)) {
1093 /* byref(c_char(...)) */
1094 PyCArgObject *a = (PyCArgObject *)value;
1095 StgDictObject *dict = PyObject_stgdict(a->obj);
1096 if (dict && (dict->setfunc == getentry("u")->setfunc)) {
1097 Py_INCREF(value);
1098 return value;
1101 /* XXX better message */
1102 PyErr_SetString(PyExc_TypeError,
1103 "wrong type");
1104 return NULL;
1107 static PyObject *
1108 c_char_p_from_param(PyObject *type, PyObject *value)
1110 #if (PYTHON_API_VERSION < 1012)
1111 # error not supported
1112 #endif
1113 if (value == Py_None) {
1114 Py_INCREF(Py_None);
1115 return Py_None;
1117 if (PyString_Check(value) || PyUnicode_Check(value)) {
1118 PyCArgObject *parg;
1119 struct fielddesc *fd = getentry("z");
1121 parg = new_CArgObject();
1122 parg->pffi_type = &ffi_type_pointer;
1123 parg->tag = 'z';
1124 parg->obj = fd->setfunc(&parg->value, value, 0);
1125 if (parg->obj == NULL) {
1126 Py_DECREF(parg);
1127 return NULL;
1129 return (PyObject *)parg;
1131 if (PyObject_IsInstance(value, type)) {
1132 Py_INCREF(value);
1133 return value;
1135 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1136 /* c_char array instance or pointer(c_char(...)) */
1137 StgDictObject *dt = PyObject_stgdict(value);
1138 StgDictObject *dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL;
1139 if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1140 Py_INCREF(value);
1141 return value;
1144 if (PyCArg_CheckExact(value)) {
1145 /* byref(c_char(...)) */
1146 PyCArgObject *a = (PyCArgObject *)value;
1147 StgDictObject *dict = PyObject_stgdict(a->obj);
1148 if (dict && (dict->setfunc == getentry("c")->setfunc)) {
1149 Py_INCREF(value);
1150 return value;
1153 /* XXX better message */
1154 PyErr_SetString(PyExc_TypeError,
1155 "wrong type");
1156 return NULL;
1159 static PyObject *
1160 c_void_p_from_param(PyObject *type, PyObject *value)
1162 StgDictObject *stgd;
1163 #if (PYTHON_API_VERSION < 1012)
1164 # error not supported
1165 #endif
1167 /* None */
1168 if (value == Py_None) {
1169 Py_INCREF(Py_None);
1170 return Py_None;
1172 /* Should probably allow buffer interface as well */
1173 /* int, long */
1174 if (PyInt_Check(value) || PyLong_Check(value)) {
1175 PyCArgObject *parg;
1176 struct fielddesc *fd = getentry("P");
1178 parg = new_CArgObject();
1179 parg->pffi_type = &ffi_type_pointer;
1180 parg->tag = 'P';
1181 parg->obj = fd->setfunc(&parg->value, value, 0);
1182 if (parg->obj == NULL) {
1183 Py_DECREF(parg);
1184 return NULL;
1186 return (PyObject *)parg;
1188 /* string */
1189 if (PyString_Check(value)) {
1190 PyCArgObject *parg;
1191 struct fielddesc *fd = getentry("z");
1193 parg = new_CArgObject();
1194 parg->pffi_type = &ffi_type_pointer;
1195 parg->tag = 'z';
1196 parg->obj = fd->setfunc(&parg->value, value, 0);
1197 if (parg->obj == NULL) {
1198 Py_DECREF(parg);
1199 return NULL;
1201 return (PyObject *)parg;
1203 /* unicode */
1204 if (PyUnicode_Check(value)) {
1205 PyCArgObject *parg;
1206 struct fielddesc *fd = getentry("Z");
1208 parg = new_CArgObject();
1209 parg->pffi_type = &ffi_type_pointer;
1210 parg->tag = 'Z';
1211 parg->obj = fd->setfunc(&parg->value, value, 0);
1212 if (parg->obj == NULL) {
1213 Py_DECREF(parg);
1214 return NULL;
1216 return (PyObject *)parg;
1218 /* c_void_p instance (or subclass) */
1219 if (PyObject_IsInstance(value, type)) {
1220 /* c_void_p instances */
1221 Py_INCREF(value);
1222 return value;
1224 /* ctypes array or pointer instance */
1225 if (ArrayObject_Check(value) || PointerObject_Check(value)) {
1226 /* Any array or pointer is accepted */
1227 Py_INCREF(value);
1228 return value;
1230 /* byref(...) */
1231 if (PyCArg_CheckExact(value)) {
1232 /* byref(c_xxx()) */
1233 PyCArgObject *a = (PyCArgObject *)value;
1234 if (a->tag == 'P') {
1235 Py_INCREF(value);
1236 return value;
1239 /* function pointer */
1240 if (CFuncPtrObject_Check(value)) {
1241 PyCArgObject *parg;
1242 CFuncPtrObject *func;
1243 func = (CFuncPtrObject *)value;
1244 parg = new_CArgObject();
1245 parg->pffi_type = &ffi_type_pointer;
1246 parg->tag = 'P';
1247 Py_INCREF(value);
1248 parg->value.p = *(void **)func->b_ptr;
1249 parg->obj = value;
1250 return (PyObject *)parg;
1252 /* c_char_p, c_wchar_p */
1253 stgd = PyObject_stgdict(value);
1254 if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
1255 PyCArgObject *parg;
1257 switch (PyString_AS_STRING(stgd->proto)[0]) {
1258 case 'z': /* c_char_p */
1259 case 'Z': /* c_wchar_p */
1260 parg = new_CArgObject();
1261 if (parg == NULL)
1262 return NULL;
1263 parg->pffi_type = &ffi_type_pointer;
1264 parg->tag = 'Z';
1265 Py_INCREF(value);
1266 parg->obj = value;
1267 /* Remember: b_ptr points to where the pointer is stored! */
1268 parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
1269 return (PyObject *)parg;
1272 /* XXX better message */
1273 PyErr_SetString(PyExc_TypeError,
1274 "wrong type");
1275 return NULL;
1277 #if (PYTHON_API_VERSION >= 1012)
1279 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O };
1280 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
1281 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
1283 #else
1284 #error
1285 static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_VARARGS };
1286 static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_VARARGS };
1287 static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_VARARGS };
1289 #endif
1291 static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
1292 PyObject *proto, struct fielddesc *fmt)
1294 PyTypeObject *result;
1295 StgDictObject *stgdict;
1296 PyObject *name = PyTuple_GET_ITEM(args, 0);
1297 PyObject *swapped_args;
1298 static PyObject *suffix;
1299 Py_ssize_t i;
1301 swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
1302 if (!swapped_args)
1303 return NULL;
1305 if (suffix == NULL)
1306 #ifdef WORDS_BIGENDIAN
1307 suffix = PyString_FromString("_le");
1308 #else
1309 suffix = PyString_FromString("_be");
1310 #endif
1312 Py_INCREF(name);
1313 PyString_Concat(&name, suffix);
1314 if (name == NULL)
1315 return NULL;
1317 PyTuple_SET_ITEM(swapped_args, 0, name);
1318 for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
1319 PyObject *v = PyTuple_GET_ITEM(args, i);
1320 Py_INCREF(v);
1321 PyTuple_SET_ITEM(swapped_args, i, v);
1324 /* create the new instance (which is a class,
1325 since we are a metatype!) */
1326 result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
1327 Py_DECREF(swapped_args);
1328 if (result == NULL)
1329 return NULL;
1331 stgdict = (StgDictObject *)PyObject_CallObject(
1332 (PyObject *)&StgDict_Type, NULL);
1333 if (!stgdict) /* XXX leaks result! */
1334 return NULL;
1336 stgdict->ffi_type_pointer = *fmt->pffi_type;
1337 stgdict->align = fmt->pffi_type->alignment;
1338 stgdict->length = 0;
1339 stgdict->size = fmt->pffi_type->size;
1340 stgdict->setfunc = fmt->setfunc_swapped;
1341 stgdict->getfunc = fmt->getfunc_swapped;
1343 Py_INCREF(proto);
1344 stgdict->proto = proto;
1346 /* replace the class dict by our updated spam dict */
1347 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1348 Py_DECREF(result);
1349 Py_DECREF((PyObject *)stgdict);
1350 return NULL;
1352 Py_DECREF(result->tp_dict);
1353 result->tp_dict = (PyObject *)stgdict;
1355 return (PyObject *)result;
1359 static PyObject *
1360 SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1362 PyTypeObject *result;
1363 StgDictObject *stgdict;
1364 PyObject *proto;
1365 PyMethodDef *ml;
1366 struct fielddesc *fmt;
1368 /* create the new instance (which is a class,
1369 since we are a metatype!) */
1370 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1371 if (result == NULL)
1372 return NULL;
1374 proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1375 if (!proto
1376 || !PyString_Check(proto)
1377 || 1 != strlen(PyString_AS_STRING(proto))
1378 || !strchr(SIMPLE_TYPE_CHARS, PyString_AS_STRING(proto)[0])) {
1379 PyErr_Format(PyExc_AttributeError,
1380 "class must define a '_type_' attribute which must be\n"
1381 "a single character string containing one of '%s'.",
1382 SIMPLE_TYPE_CHARS);
1383 Py_XDECREF(proto);
1384 Py_DECREF(result);
1385 return NULL;
1387 fmt = getentry(PyString_AS_STRING(proto));
1388 if (fmt == NULL) {
1389 Py_DECREF(result);
1390 PyErr_Format(PyExc_ValueError,
1391 "_type_ '%s' not supported",
1392 PyString_AS_STRING(proto));
1393 return NULL;
1396 stgdict = (StgDictObject *)PyObject_CallObject(
1397 (PyObject *)&StgDict_Type, NULL);
1398 if (!stgdict)
1399 return NULL;
1401 stgdict->ffi_type_pointer = *fmt->pffi_type;
1402 stgdict->align = fmt->pffi_type->alignment;
1403 stgdict->length = 0;
1404 stgdict->size = fmt->pffi_type->size;
1405 stgdict->setfunc = fmt->setfunc;
1406 stgdict->getfunc = fmt->getfunc;
1408 if (result->tp_base != &Simple_Type) {
1409 stgdict->setfunc = NULL;
1410 stgdict->getfunc = NULL;
1414 /* This consumes the refcount on proto which we have */
1415 stgdict->proto = proto;
1417 /* replace the class dict by our updated spam dict */
1418 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1419 Py_DECREF(result);
1420 Py_DECREF((PyObject *)stgdict);
1421 return NULL;
1423 Py_DECREF(result->tp_dict);
1424 result->tp_dict = (PyObject *)stgdict;
1426 /* Install from_param class methods in ctypes base classes.
1427 Overrides the SimpleType_from_param generic method.
1429 if (result->tp_base == &Simple_Type) {
1430 switch (PyString_AS_STRING(proto)[0]) {
1431 case 'z': /* c_char_p */
1432 ml = &c_char_p_method;
1433 break;
1434 case 'Z': /* c_wchar_p */
1435 ml = &c_wchar_p_method;
1436 break;
1437 case 'P': /* c_void_p */
1438 ml = &c_void_p_method;
1439 break;
1440 default:
1441 ml = NULL;
1442 break;
1445 if (ml) {
1446 #if (PYTHON_API_VERSION >= 1012)
1447 PyObject *meth;
1448 int x;
1449 meth = PyDescr_NewClassMethod(result, ml);
1450 if (!meth)
1451 return NULL;
1452 #else
1453 #error
1454 PyObject *meth, *func;
1455 int x;
1456 func = PyCFunction_New(ml, NULL);
1457 if (!func)
1458 return NULL;
1459 meth = PyObject_CallFunctionObjArgs(
1460 (PyObject *)&PyClassMethod_Type,
1461 func, NULL);
1462 Py_DECREF(func);
1463 if (!meth) {
1464 return NULL;
1466 #endif
1467 x = PyDict_SetItemString(result->tp_dict,
1468 ml->ml_name,
1469 meth);
1470 Py_DECREF(meth);
1471 if (x == -1) {
1472 Py_DECREF(result);
1473 return NULL;
1478 if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
1479 PyObject *swapped = CreateSwappedType(type, args, kwds,
1480 proto, fmt);
1481 if (swapped == NULL) {
1482 Py_DECREF(result);
1483 return NULL;
1485 #ifdef WORDS_BIGENDIAN
1486 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
1487 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
1488 PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
1489 PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
1490 #else
1491 PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
1492 PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
1493 PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
1494 PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
1495 #endif
1496 Py_DECREF(swapped);
1499 return (PyObject *)result;
1503 * This is a *class method*.
1504 * Convert a parameter into something that ConvParam can handle.
1506 * This is either an instance of the requested type, a Python integer, or a
1507 * 'magic' 3-tuple.
1509 * (These are somewhat related to Martin v. Loewis 'Enhanced Argument Tuples',
1510 * described in PEP 286.)
1512 * The tuple must contain
1514 * - a format character, currently 'ifdqc' are understood
1515 * which will inform ConvParam about how to push the argument on the stack.
1517 * - a corresponding Python object: i - integer, f - float, d - float,
1518 * q - longlong, c - integer
1520 * - any object which can be used to keep the original parameter alive
1521 * as long as the tuple lives.
1523 static PyObject *
1524 SimpleType_from_param(PyObject *type, PyObject *value)
1526 StgDictObject *dict;
1527 char *fmt;
1528 PyCArgObject *parg;
1529 struct fielddesc *fd;
1531 /* If the value is already an instance of the requested type,
1532 we can use it as is */
1533 if (1 == PyObject_IsInstance(value, type)) {
1534 Py_INCREF(value);
1535 return value;
1538 dict = PyType_stgdict(type);
1539 assert(dict);
1541 /* I think we can rely on this being a one-character string */
1542 fmt = PyString_AsString(dict->proto);
1543 assert(fmt);
1545 fd = getentry(fmt);
1546 assert(fd);
1548 parg = new_CArgObject();
1549 if (parg == NULL)
1550 return NULL;
1552 parg->tag = fmt[0];
1553 parg->pffi_type = fd->pffi_type;
1554 parg->obj = fd->setfunc(&parg->value, value, 0);
1555 if (parg->obj == NULL) {
1556 Py_DECREF(parg);
1557 return NULL;
1559 return (PyObject *)parg;
1562 static PyMethodDef SimpleType_methods[] = {
1563 { "from_param", SimpleType_from_param, METH_O, from_param_doc },
1564 { "from_address", CDataType_from_address, METH_O, from_address_doc },
1565 { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc},
1566 { NULL, NULL },
1569 PyTypeObject SimpleType_Type = {
1570 PyObject_HEAD_INIT(NULL)
1571 0, /* ob_size */
1572 "_ctypes.SimpleType", /* tp_name */
1573 0, /* tp_basicsize */
1574 0, /* tp_itemsize */
1575 0, /* tp_dealloc */
1576 0, /* tp_print */
1577 0, /* tp_getattr */
1578 0, /* tp_setattr */
1579 0, /* tp_compare */
1580 0, /* tp_repr */
1581 0, /* tp_as_number */
1582 &CDataType_as_sequence, /* tp_as_sequence */
1583 0, /* tp_as_mapping */
1584 0, /* tp_hash */
1585 0, /* tp_call */
1586 0, /* tp_str */
1587 0, /* tp_getattro */
1588 0, /* tp_setattro */
1589 0, /* tp_as_buffer */
1590 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1591 "metatype for the SimpleType Objects", /* tp_doc */
1592 0, /* tp_traverse */
1593 0, /* tp_clear */
1594 0, /* tp_richcompare */
1595 0, /* tp_weaklistoffset */
1596 0, /* tp_iter */
1597 0, /* tp_iternext */
1598 SimpleType_methods, /* tp_methods */
1599 0, /* tp_members */
1600 0, /* tp_getset */
1601 0, /* tp_base */
1602 0, /* tp_dict */
1603 0, /* tp_descr_get */
1604 0, /* tp_descr_set */
1605 0, /* tp_dictoffset */
1606 0, /* tp_init */
1607 0, /* tp_alloc */
1608 SimpleType_new, /* tp_new */
1609 0, /* tp_free */
1612 /******************************************************************/
1614 CFuncPtrType_Type
1617 static PyObject *
1618 converters_from_argtypes(PyObject *ob)
1620 PyObject *converters;
1621 int i;
1622 int nArgs;
1624 ob = PySequence_Tuple(ob); /* new reference */
1625 if (!ob) {
1626 PyErr_SetString(PyExc_TypeError,
1627 "_argtypes_ must be a sequence of types");
1628 return NULL;
1631 nArgs = PyTuple_GET_SIZE(ob);
1632 converters = PyTuple_New(nArgs);
1633 if (!converters)
1634 return NULL;
1636 /* I have to check if this is correct. Using c_char, which has a size
1637 of 1, will be assumed to be pushed as only one byte!
1638 Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
1641 for (i = 0; i < nArgs; ++i) {
1642 PyObject *tp = PyTuple_GET_ITEM(ob, i);
1643 PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
1644 if (!cnv)
1645 goto argtypes_error_1;
1646 PyTuple_SET_ITEM(converters, i, cnv);
1648 Py_DECREF(ob);
1649 return converters;
1651 argtypes_error_1:
1652 Py_XDECREF(converters);
1653 Py_DECREF(ob);
1654 PyErr_Format(PyExc_TypeError,
1655 "item %d in _argtypes_ has no from_param method", i+1);
1656 return NULL;
1659 static int
1660 make_funcptrtype_dict(StgDictObject *stgdict)
1662 PyObject *ob;
1663 PyObject *converters = NULL;
1665 stgdict->align = getentry("P")->pffi_type->alignment;
1666 stgdict->length = 1;
1667 stgdict->size = sizeof(void *);
1668 stgdict->setfunc = NULL;
1669 stgdict->getfunc = NULL;
1670 stgdict->ffi_type_pointer = ffi_type_pointer;
1672 ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
1673 if (!ob || !PyInt_Check(ob)) {
1674 PyErr_SetString(PyExc_TypeError,
1675 "class must define _flags_ which must be an integer");
1676 return -1;
1678 stgdict->flags = PyInt_AS_LONG(ob);
1680 /* _argtypes_ is optional... */
1681 ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
1682 if (ob) {
1683 converters = converters_from_argtypes(ob);
1684 if (!converters)
1685 goto error;
1686 Py_INCREF(ob);
1687 stgdict->argtypes = ob;
1688 stgdict->converters = converters;
1691 ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_");
1692 if (ob) {
1693 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
1694 PyErr_SetString(PyExc_TypeError,
1695 "_restype_ must be a type, a callable, or None");
1696 return -1;
1698 Py_INCREF(ob);
1699 stgdict->restype = ob;
1700 stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_");
1701 if (stgdict->checker == NULL)
1702 PyErr_Clear();
1704 /* XXX later, maybe.
1705 ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_");
1706 if (ob) {
1707 if (!PyCallable_Check(ob)) {
1708 PyErr_SetString(PyExc_TypeError,
1709 "_errcheck_ must be callable");
1710 return -1;
1712 Py_INCREF(ob);
1713 stgdict->errcheck = ob;
1716 return 0;
1718 error:
1719 Py_XDECREF(converters);
1720 return -1;
1724 static PyObject *
1725 CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1727 PyTypeObject *result;
1728 StgDictObject *stgdict;
1730 stgdict = (StgDictObject *)PyObject_CallObject(
1731 (PyObject *)&StgDict_Type, NULL);
1732 if (!stgdict)
1733 return NULL;
1735 /* create the new instance (which is a class,
1736 since we are a metatype!) */
1737 result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1738 if (result == NULL) {
1739 Py_DECREF((PyObject *)stgdict);
1740 return NULL;
1743 /* replace the class dict by our updated storage dict */
1744 if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) {
1745 Py_DECREF(result);
1746 Py_DECREF((PyObject *)stgdict);
1747 return NULL;
1749 Py_DECREF(result->tp_dict);
1750 result->tp_dict = (PyObject *)stgdict;
1752 if (-1 == make_funcptrtype_dict(stgdict)) {
1753 Py_DECREF(result);
1754 return NULL;
1757 return (PyObject *)result;
1760 PyTypeObject CFuncPtrType_Type = {
1761 PyObject_HEAD_INIT(NULL)
1762 0, /* ob_size */
1763 "_ctypes.CFuncPtrType", /* tp_name */
1764 0, /* tp_basicsize */
1765 0, /* tp_itemsize */
1766 0, /* tp_dealloc */
1767 0, /* tp_print */
1768 0, /* tp_getattr */
1769 0, /* tp_setattr */
1770 0, /* tp_compare */
1771 0, /* tp_repr */
1772 0, /* tp_as_number */
1773 &CDataType_as_sequence, /* tp_as_sequence */
1774 0, /* tp_as_mapping */
1775 0, /* tp_hash */
1776 0, /* tp_call */
1777 0, /* tp_str */
1778 0, /* tp_getattro */
1779 0, /* tp_setattro */
1780 0, /* tp_as_buffer */
1781 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1782 "metatype for C function pointers", /* tp_doc */
1783 (traverseproc)CDataType_traverse, /* tp_traverse */
1784 (inquiry)CDataType_clear, /* tp_clear */
1785 0, /* tp_richcompare */
1786 0, /* tp_weaklistoffset */
1787 0, /* tp_iter */
1788 0, /* tp_iternext */
1789 CDataType_methods, /* tp_methods */
1790 0, /* tp_members */
1791 0, /* tp_getset */
1792 0, /* tp_base */
1793 0, /* tp_dict */
1794 0, /* tp_descr_get */
1795 0, /* tp_descr_set */
1796 0, /* tp_dictoffset */
1797 0, /* tp_init */
1798 0, /* tp_alloc */
1799 CFuncPtrType_new, /* tp_new */
1800 0, /* tp_free */
1804 /*****************************************************************
1805 * Code to keep needed objects alive
1808 static CDataObject *
1809 CData_GetContainer(CDataObject *self)
1811 while (self->b_base)
1812 self = self->b_base;
1813 if (self->b_objects == NULL) {
1814 if (self->b_length) {
1815 self->b_objects = PyDict_New();
1816 } else {
1817 Py_INCREF(Py_None);
1818 self->b_objects = Py_None;
1821 return self;
1824 static PyObject *
1825 GetKeepedObjects(CDataObject *target)
1827 return CData_GetContainer(target)->b_objects;
1830 static PyObject *
1831 unique_key(CDataObject *target, Py_ssize_t index)
1833 char string[256];
1834 char *cp = string;
1835 size_t bytes_left;
1837 assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
1838 #if (PY_VERSION_HEX < 0x02050000)
1839 cp += sprintf(cp, "%x", index);
1840 #else
1841 cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
1842 #endif
1843 while (target->b_base) {
1844 bytes_left = sizeof(string) - (cp - string) - 1;
1845 /* Hex format needs 2 characters per byte */
1846 if (bytes_left < sizeof(Py_ssize_t) * 2) {
1847 PyErr_SetString(PyExc_ValueError,
1848 "ctypes object structure too deep");
1849 return NULL;
1851 #if (PY_VERSION_HEX < 0x02050000)
1852 cp += sprintf(cp, ":%x", (int)target->b_index);
1853 #else
1854 cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
1855 #endif
1856 target = target->b_base;
1858 return PyString_FromStringAndSize(string, cp-string);
1862 * Keep a reference to 'keep' in the 'target', at index 'index'.
1864 * If 'keep' is None, do nothing.
1866 * Otherwise create a dictionary (if it does not yet exist) id the root
1867 * objects 'b_objects' item, which will store the 'keep' object under a unique
1868 * key.
1870 * The unique_key helper travels the target's b_base pointer down to the root,
1871 * building a string containing hex-formatted indexes found during traversal,
1872 * separated by colons.
1874 * The index tuple is used as a key into the root object's b_objects dict.
1876 * Note: This function steals a refcount of the third argument, even if it
1877 * fails!
1879 static int
1880 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
1882 int result;
1883 CDataObject *ob;
1884 PyObject *key;
1886 /* Optimization: no need to store None */
1887 if (keep == Py_None) {
1888 Py_DECREF(Py_None);
1889 return 0;
1891 ob = CData_GetContainer(target);
1892 if (ob->b_objects == NULL || !PyDict_Check(ob->b_objects)) {
1893 Py_XDECREF(ob->b_objects);
1894 ob->b_objects = keep; /* refcount consumed */
1895 return 0;
1897 key = unique_key(target, index);
1898 if (key == NULL) {
1899 Py_DECREF(keep);
1900 return -1;
1902 result = PyDict_SetItem(ob->b_objects, key, keep);
1903 Py_DECREF(key);
1904 Py_DECREF(keep);
1905 return result;
1908 /******************************************************************/
1910 CData_Type
1912 static int
1913 CData_traverse(CDataObject *self, visitproc visit, void *arg)
1915 Py_VISIT(self->b_objects);
1916 Py_VISIT((PyObject *)self->b_base);
1917 return 0;
1920 static int
1921 CData_clear(CDataObject *self)
1923 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
1924 Py_CLEAR(self->b_objects);
1925 if ((self->b_needsfree)
1926 && ((size_t)dict->size > sizeof(self->b_value)))
1927 PyMem_Free(self->b_ptr);
1928 self->b_ptr = NULL;
1929 Py_CLEAR(self->b_base);
1930 return 0;
1933 static void
1934 CData_dealloc(PyObject *self)
1936 CData_clear((CDataObject *)self);
1937 self->ob_type->tp_free(self);
1940 static PyMemberDef CData_members[] = {
1941 { "_b_base_", T_OBJECT,
1942 offsetof(CDataObject, b_base), READONLY,
1943 "the base object" },
1944 { "_b_needsfree_", T_INT,
1945 offsetof(CDataObject, b_needsfree), READONLY,
1946 "whether the object owns the memory or not" },
1947 { "_objects", T_OBJECT,
1948 offsetof(CDataObject, b_objects), READONLY,
1949 "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
1950 { NULL },
1953 static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
1955 CDataObject *self = (CDataObject *)_self;
1956 if (seg != 0) {
1957 /* Hm. Must this set an exception? */
1958 return -1;
1960 *pptr = self->b_ptr;
1961 return self->b_size;
1964 static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
1966 if (lenp)
1967 *lenp = 1;
1968 return 1;
1971 static PyBufferProcs CData_as_buffer = {
1972 CData_GetBuffer,
1973 CData_GetBuffer,
1974 CData_GetSegcount,
1975 NULL,
1979 * CData objects are mutable, so they cannot be hashable!
1981 static long
1982 CData_nohash(PyObject *self)
1984 PyErr_SetString(PyExc_TypeError, "unhashable type");
1985 return -1;
1989 * default __ctypes_from_outparam__ method returns self.
1991 static PyObject *
1992 CData_from_outparam(PyObject *self, PyObject *args)
1994 Py_INCREF(self);
1995 return self;
1998 static PyMethodDef CData_methods[] = {
1999 { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
2000 { NULL, NULL },
2003 PyTypeObject CData_Type = {
2004 PyObject_HEAD_INIT(NULL)
2006 "_ctypes._CData",
2007 sizeof(CDataObject), /* tp_basicsize */
2008 0, /* tp_itemsize */
2009 CData_dealloc, /* tp_dealloc */
2010 0, /* tp_print */
2011 0, /* tp_getattr */
2012 0, /* tp_setattr */
2013 0, /* tp_compare */
2014 0, /* tp_repr */
2015 0, /* tp_as_number */
2016 0, /* tp_as_sequence */
2017 0, /* tp_as_mapping */
2018 CData_nohash, /* tp_hash */
2019 0, /* tp_call */
2020 0, /* tp_str */
2021 0, /* tp_getattro */
2022 0, /* tp_setattro */
2023 &CData_as_buffer, /* tp_as_buffer */
2024 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2025 "XXX to be provided", /* tp_doc */
2026 (traverseproc)CData_traverse, /* tp_traverse */
2027 (inquiry)CData_clear, /* tp_clear */
2028 0, /* tp_richcompare */
2029 0, /* tp_weaklistoffset */
2030 0, /* tp_iter */
2031 0, /* tp_iternext */
2032 CData_methods, /* tp_methods */
2033 CData_members, /* tp_members */
2034 0, /* tp_getset */
2035 0, /* tp_base */
2036 0, /* tp_dict */
2037 0, /* tp_descr_get */
2038 0, /* tp_descr_set */
2039 0, /* tp_dictoffset */
2040 0, /* tp_init */
2041 0, /* tp_alloc */
2042 0, /* tp_new */
2043 0, /* tp_free */
2046 static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
2048 if ((size_t)dict->size <= sizeof(obj->b_value)) {
2049 /* No need to call malloc, can use the default buffer */
2050 obj->b_ptr = (char *)&obj->b_value;
2051 obj->b_needsfree = 1;
2052 } else {
2053 /* In python 2.4, and ctypes 0.9.6, the malloc call took about
2054 33% of the creation time for c_int().
2056 obj->b_ptr = (char *)PyMem_Malloc(dict->size);
2057 obj->b_needsfree = 1;
2058 memset(obj->b_ptr, 0, dict->size);
2060 obj->b_size = dict->size;
2063 PyObject *
2064 CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
2066 CDataObject *cmem;
2067 StgDictObject *dict;
2069 assert(PyType_Check(type));
2070 dict = PyType_stgdict(type);
2071 if (!dict) {
2072 PyErr_SetString(PyExc_TypeError,
2073 "abstract class");
2074 return NULL;
2076 dict->flags |= DICTFLAG_FINAL;
2077 cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2078 if (cmem == NULL)
2079 return NULL;
2080 assert(CDataObject_Check(cmem));
2082 cmem->b_length = dict->length;
2083 cmem->b_size = dict->size;
2084 if (base) { /* use base's buffer */
2085 assert(CDataObject_Check(base));
2086 cmem->b_ptr = adr;
2087 cmem->b_needsfree = 0;
2088 Py_INCREF(base);
2089 cmem->b_base = (CDataObject *)base;
2090 cmem->b_index = index;
2091 } else { /* copy contents of adr */
2092 CData_MallocBuffer(cmem, dict);
2093 memcpy(cmem->b_ptr, adr, dict->size);
2094 cmem->b_index = index;
2096 return (PyObject *)cmem;
2100 Box a memory block into a CData instance.
2102 PyObject *
2103 CData_AtAddress(PyObject *type, void *buf)
2105 CDataObject *pd;
2106 StgDictObject *dict;
2108 assert(PyType_Check(type));
2109 dict = PyType_stgdict(type);
2110 if (!dict) {
2111 PyErr_SetString(PyExc_TypeError,
2112 "abstract class");
2113 return NULL;
2115 dict->flags |= DICTFLAG_FINAL;
2117 pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
2118 if (!pd)
2119 return NULL;
2120 assert(CDataObject_Check(pd));
2121 pd->b_ptr = (char *)buf;
2122 pd->b_length = dict->length;
2123 pd->b_size = dict->size;
2124 return (PyObject *)pd;
2128 This function returns TRUE for c_int, c_void_p, and these kind of
2129 classes. FALSE otherwise FALSE also for subclasses of c_int and
2130 such.
2132 int IsSimpleSubType(PyObject *obj)
2134 PyTypeObject *type = (PyTypeObject *)obj;
2136 if (SimpleTypeObject_Check(type))
2137 return type->tp_base != &Simple_Type;
2138 return 0;
2141 PyObject *
2142 CData_get(PyObject *type, GETFUNC getfunc, PyObject *src,
2143 Py_ssize_t index, Py_ssize_t size, char *adr)
2145 StgDictObject *dict;
2146 if (getfunc)
2147 return getfunc(adr, size);
2148 assert(type);
2149 dict = PyType_stgdict(type);
2150 if (dict && dict->getfunc && !IsSimpleSubType(type))
2151 return dict->getfunc(adr, size);
2152 return CData_FromBaseObj(type, src, index, adr);
2156 Helper function for CData_set below.
2158 static PyObject *
2159 _CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2160 Py_ssize_t size, char *ptr)
2162 CDataObject *src;
2164 if (setfunc)
2165 return setfunc(ptr, value, size);
2167 if (!CDataObject_Check(value)) {
2168 StgDictObject *dict = PyType_stgdict(type);
2169 if (dict && dict->setfunc)
2170 return dict->setfunc(ptr, value, size);
2172 If value is a tuple, we try to call the type with the tuple
2173 and use the result!
2175 assert(PyType_Check(type));
2176 if (PyTuple_Check(value)) {
2177 PyObject *ob;
2178 PyObject *result;
2179 ob = PyObject_CallObject(type, value);
2180 if (ob == NULL) {
2181 Extend_Error_Info(PyExc_RuntimeError, "(%s) ",
2182 ((PyTypeObject *)type)->tp_name);
2183 return NULL;
2185 result = _CData_set(dst, type, setfunc, ob,
2186 size, ptr);
2187 Py_DECREF(ob);
2188 return result;
2189 } else if (value == Py_None && PointerTypeObject_Check(type)) {
2190 *(void **)ptr = NULL;
2191 Py_INCREF(Py_None);
2192 return Py_None;
2193 } else {
2194 PyErr_Format(PyExc_TypeError,
2195 "expected %s instance, got %s",
2196 ((PyTypeObject *)type)->tp_name,
2197 value->ob_type->tp_name);
2198 return NULL;
2201 src = (CDataObject *)value;
2203 if (PyObject_IsInstance(value, type)) {
2204 memcpy(ptr,
2205 src->b_ptr,
2206 size);
2208 if (PointerTypeObject_Check(type))
2209 /* XXX */;
2211 value = GetKeepedObjects(src);
2212 Py_INCREF(value);
2213 return value;
2216 if (PointerTypeObject_Check(type)
2217 && ArrayObject_Check(value)) {
2218 StgDictObject *p1, *p2;
2219 PyObject *keep;
2220 p1 = PyObject_stgdict(value);
2221 p2 = PyType_stgdict(type);
2223 if (p1->proto != p2->proto) {
2224 PyErr_Format(PyExc_TypeError,
2225 "incompatible types, %s instance instead of %s instance",
2226 value->ob_type->tp_name,
2227 ((PyTypeObject *)type)->tp_name);
2228 return NULL;
2230 *(void **)ptr = src->b_ptr;
2232 keep = GetKeepedObjects(src);
2234 We are assigning an array object to a field which represents
2235 a pointer. This has the same effect as converting an array
2236 into a pointer. So, again, we have to keep the whole object
2237 pointed to (which is the array in this case) alive, and not
2238 only it's object list. So we create a tuple, containing
2239 b_objects list PLUS the array itself, and return that!
2241 return Py_BuildValue("(OO)", keep, value);
2243 PyErr_Format(PyExc_TypeError,
2244 "incompatible types, %s instance instead of %s instance",
2245 value->ob_type->tp_name,
2246 ((PyTypeObject *)type)->tp_name);
2247 return NULL;
2251 * Set a slice in object 'dst', which has the type 'type',
2252 * to the value 'value'.
2255 CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
2256 Py_ssize_t index, Py_ssize_t size, char *ptr)
2258 CDataObject *mem = (CDataObject *)dst;
2259 PyObject *result;
2261 if (!CDataObject_Check(dst)) {
2262 PyErr_SetString(PyExc_TypeError,
2263 "not a ctype instance");
2264 return -1;
2267 result = _CData_set(mem, type, setfunc, value,
2268 size, ptr);
2269 if (result == NULL)
2270 return -1;
2272 /* KeepRef steals a refcount from it's last argument */
2273 /* If KeepRef fails, we are stumped. The dst memory block has already
2274 been changed */
2275 return KeepRef(mem, index, result);
2279 /******************************************************************/
2280 static PyObject *
2281 GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2283 CDataObject *obj;
2284 StgDictObject *dict;
2286 dict = PyType_stgdict((PyObject *)type);
2287 if (!dict) {
2288 PyErr_SetString(PyExc_TypeError,
2289 "abstract class");
2290 return NULL;
2292 dict->flags |= DICTFLAG_FINAL;
2294 obj = (CDataObject *)type->tp_alloc(type, 0);
2295 if (!obj)
2296 return NULL;
2298 obj->b_base = NULL;
2299 obj->b_index = 0;
2300 obj->b_objects = NULL;
2301 obj->b_length = dict->length;
2303 CData_MallocBuffer(obj, dict);
2304 return (PyObject *)obj;
2306 /*****************************************************************/
2308 CFuncPtr_Type
2311 static PyObject *
2312 CFuncPtr_as_parameter(CDataObject *self)
2314 PyCArgObject *parg;
2316 parg = new_CArgObject();
2317 if (parg == NULL)
2318 return NULL;
2320 parg->tag = 'P';
2321 parg->pffi_type = &ffi_type_pointer;
2322 Py_INCREF(self);
2323 parg->obj = (PyObject *)self;
2324 parg->value.p = *(void **)self->b_ptr;
2325 return (PyObject *)parg;
2328 static int
2329 CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob)
2331 if (ob && !PyCallable_Check(ob)) {
2332 PyErr_SetString(PyExc_TypeError,
2333 "the errcheck attribute must be callable");
2334 return -1;
2336 Py_XDECREF(self->errcheck);
2337 Py_XINCREF(ob);
2338 self->errcheck = ob;
2339 return 0;
2342 static PyObject *
2343 CFuncPtr_get_errcheck(CFuncPtrObject *self)
2345 if (self->errcheck) {
2346 Py_INCREF(self->errcheck);
2347 return self->errcheck;
2349 Py_INCREF(Py_None);
2350 return Py_None;
2353 static int
2354 CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob)
2356 if (ob == NULL) {
2357 Py_XDECREF(self->restype);
2358 self->restype = NULL;
2359 Py_XDECREF(self->checker);
2360 self->checker = NULL;
2361 return 0;
2363 if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
2364 PyErr_SetString(PyExc_TypeError,
2365 "restype must be a type, a callable, or None");
2366 return -1;
2368 Py_XDECREF(self->checker);
2369 Py_XDECREF(self->restype);
2370 Py_INCREF(ob);
2371 self->restype = ob;
2372 self->checker = PyObject_GetAttrString(ob, "_check_retval_");
2373 if (self->checker == NULL)
2374 PyErr_Clear();
2375 return 0;
2378 static PyObject *
2379 CFuncPtr_get_restype(CFuncPtrObject *self)
2381 StgDictObject *dict;
2382 if (self->restype) {
2383 Py_INCREF(self->restype);
2384 return self->restype;
2386 dict = PyObject_stgdict((PyObject *)self);
2387 assert(dict);
2388 if (dict->restype) {
2389 Py_INCREF(dict->restype);
2390 return dict->restype;
2391 } else {
2392 Py_INCREF(Py_None);
2393 return Py_None;
2397 static int
2398 CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob)
2400 PyObject *converters;
2402 if (ob == NULL || ob == Py_None) {
2403 Py_XDECREF(self->converters);
2404 self->converters = NULL;
2405 Py_XDECREF(self->argtypes);
2406 self->argtypes = NULL;
2407 } else {
2408 converters = converters_from_argtypes(ob);
2409 if (!converters)
2410 return -1;
2411 Py_XDECREF(self->converters);
2412 self->converters = converters;
2413 Py_XDECREF(self->argtypes);
2414 Py_INCREF(ob);
2415 self->argtypes = ob;
2417 return 0;
2420 static PyObject *
2421 CFuncPtr_get_argtypes(CFuncPtrObject *self)
2423 StgDictObject *dict;
2424 if (self->argtypes) {
2425 Py_INCREF(self->argtypes);
2426 return self->argtypes;
2428 dict = PyObject_stgdict((PyObject *)self);
2429 assert(dict);
2430 if (dict->argtypes) {
2431 Py_INCREF(dict->argtypes);
2432 return dict->argtypes;
2433 } else {
2434 Py_INCREF(Py_None);
2435 return Py_None;
2439 static PyGetSetDef CFuncPtr_getsets[] = {
2440 { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck,
2441 "a function to check for errors", NULL },
2442 { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype,
2443 "specify the result type", NULL },
2444 { "argtypes", (getter)CFuncPtr_get_argtypes,
2445 (setter)CFuncPtr_set_argtypes,
2446 "specify the argument types", NULL },
2447 { "_as_parameter_", (getter)CFuncPtr_as_parameter, NULL,
2448 "return a magic value so that this can be converted to a C parameter (readonly)",
2449 NULL },
2450 { NULL, NULL }
2453 #ifdef MS_WIN32
2454 static PPROC FindAddress(void *handle, char *name, PyObject *type)
2456 PPROC address;
2457 char *mangled_name;
2458 int i;
2459 StgDictObject *dict = PyType_stgdict((PyObject *)type);
2461 address = (PPROC)GetProcAddress(handle, name);
2462 if (address)
2463 return address;
2465 if (((size_t)name & ~0xFFFF) == 0) {
2466 return NULL;
2469 /* It should not happen that dict is NULL, but better be safe */
2470 if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
2471 return address;
2473 /* for stdcall, try mangled names:
2474 funcname -> _funcname@<n>
2475 where n is 0, 4, 8, 12, ..., 128
2477 mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
2478 for (i = 0; i < 32; ++i) {
2479 sprintf(mangled_name, "_%s@%d", name, i*4);
2480 address = (PPROC)GetProcAddress(handle, mangled_name);
2481 if (address)
2482 return address;
2484 return NULL;
2486 #endif
2488 /* Return 1 if usable, 0 else and exception set. */
2489 static int
2490 _check_outarg_type(PyObject *arg, int index)
2492 StgDictObject *dict;
2494 if (PointerTypeObject_Check(arg))
2495 return 1;
2497 if (ArrayTypeObject_Check(arg))
2498 return 1;
2500 dict = PyType_stgdict(arg);
2501 if (dict
2502 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
2503 && PyString_Check(dict->proto)
2504 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
2505 && (strchr("PzZ", PyString_AS_STRING(dict->proto)[0]))) {
2506 return 1;
2509 PyErr_Format(PyExc_TypeError,
2510 "'out' parameter %d must be a pointer type, not %s",
2511 index,
2512 PyType_Check(arg) ?
2513 ((PyTypeObject *)arg)->tp_name :
2514 arg->ob_type->tp_name);
2515 return 0;
2518 /* Returns 1 on success, 0 on error */
2519 static int
2520 _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
2522 int i, len;
2523 StgDictObject *dict = PyType_stgdict((PyObject *)type);
2524 PyObject *argtypes = dict->argtypes;
2526 if (paramflags == NULL || dict->argtypes == NULL)
2527 return 1;
2529 if (!PyTuple_Check(paramflags)) {
2530 PyErr_SetString(PyExc_TypeError,
2531 "paramflags must be a tuple or None");
2532 return 0;
2535 len = PyTuple_GET_SIZE(paramflags);
2536 if (len != PyTuple_GET_SIZE(dict->argtypes)) {
2537 PyErr_SetString(PyExc_ValueError,
2538 "paramflags must have the same length as argtypes");
2539 return 0;
2542 for (i = 0; i < len; ++i) {
2543 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
2544 int flag;
2545 char *name;
2546 PyObject *defval;
2547 PyObject *typ;
2548 if (!PyArg_ParseTuple(item, "i|zO", &flag, &name, &defval)) {
2549 PyErr_SetString(PyExc_TypeError,
2550 "paramflags must be a sequence of (int [,string [,value]]) tuples");
2551 return 0;
2553 typ = PyTuple_GET_ITEM(argtypes, i);
2554 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
2555 case 0:
2556 case PARAMFLAG_FIN:
2557 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
2558 case PARAMFLAG_FIN | PARAMFLAG_FOUT:
2559 break;
2560 case PARAMFLAG_FOUT:
2561 if (!_check_outarg_type(typ, i+1))
2562 return 0;
2563 break;
2564 default:
2565 PyErr_Format(PyExc_TypeError,
2566 "paramflag value %d not supported",
2567 flag);
2568 return 0;
2571 return 1;
2574 static int
2575 _get_name(PyObject *obj, char **pname)
2577 #ifdef MS_WIN32
2578 if (PyInt_Check(obj) || PyLong_Check(obj)) {
2579 /* We have to use MAKEINTRESOURCEA for Windows CE.
2580 Works on Windows as well, of course.
2582 *pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
2583 return 1;
2585 #endif
2586 if (PyString_Check(obj) || PyUnicode_Check(obj)) {
2587 *pname = PyString_AsString(obj);
2588 return *pname ? 1 : 0;
2590 PyErr_SetString(PyExc_TypeError,
2591 "function name must be string or integer");
2592 return 0;
2596 static PyObject *
2597 CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
2599 char *name;
2600 int (* address)(void);
2601 PyObject *dll;
2602 PyObject *obj;
2603 CFuncPtrObject *self;
2604 void *handle;
2605 PyObject *paramflags = NULL;
2607 if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
2608 return NULL;
2609 if (paramflags == Py_None)
2610 paramflags = NULL;
2612 obj = PyObject_GetAttrString(dll, "_handle");
2613 if (!obj)
2614 return NULL;
2615 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
2616 PyErr_SetString(PyExc_TypeError,
2617 "the _handle attribute of the second argument must be an integer");
2618 Py_DECREF(obj);
2619 return NULL;
2621 handle = (void *)PyLong_AsVoidPtr(obj);
2622 Py_DECREF(obj);
2623 if (PyErr_Occurred()) {
2624 PyErr_SetString(PyExc_ValueError,
2625 "could not convert the _handle attribute to a pointer");
2626 return NULL;
2629 #ifdef MS_WIN32
2630 address = FindAddress(handle, name, (PyObject *)type);
2631 if (!address) {
2632 if (!IS_INTRESOURCE(name))
2633 PyErr_Format(PyExc_AttributeError,
2634 "function '%s' not found",
2635 name);
2636 else
2637 PyErr_Format(PyExc_AttributeError,
2638 "function ordinal %d not found",
2639 (WORD)(size_t)name);
2640 return NULL;
2642 #else
2643 address = (PPROC)ctypes_dlsym(handle, name);
2644 if (!address) {
2645 PyErr_Format(PyExc_AttributeError,
2646 #ifdef __CYGWIN__
2647 /* dlerror() isn't very helpful on cygwin */
2648 "function '%s' not found (%s) ",
2649 name,
2650 #endif
2651 ctypes_dlerror());
2652 return NULL;
2654 #endif
2655 if (!_validate_paramflags(type, paramflags))
2656 return NULL;
2658 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2659 if (!self)
2660 return NULL;
2662 Py_XINCREF(paramflags);
2663 self->paramflags = paramflags;
2665 *(void **)self->b_ptr = address;
2667 Py_INCREF((PyObject *)dll); /* for KeepRef */
2668 if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
2669 Py_DECREF((PyObject *)self);
2670 return NULL;
2673 Py_INCREF(self);
2674 self->callable = (PyObject *)self;
2675 return (PyObject *)self;
2678 #ifdef MS_WIN32
2679 static PyObject *
2680 CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
2682 CFuncPtrObject *self;
2683 int index;
2684 char *name = NULL;
2685 PyObject *paramflags = NULL;
2686 GUID *iid = NULL;
2687 int iid_len = 0;
2689 if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
2690 return NULL;
2691 if (paramflags == Py_None)
2692 paramflags = NULL;
2694 if (!_validate_paramflags(type, paramflags))
2695 return NULL;
2697 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2698 self->index = index + 0x1000;
2699 Py_XINCREF(paramflags);
2700 self->paramflags = paramflags;
2701 if (iid_len == sizeof(GUID))
2702 self->iid = iid;
2703 return (PyObject *)self;
2705 #endif
2708 CFuncPtr_new accepts different argument lists in addition to the standard
2709 _basespec_ keyword arg:
2711 one argument form
2712 "i" - function address
2713 "O" - must be a callable, creates a C callable function
2715 two or more argument forms (the third argument is a paramflags tuple)
2716 "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
2717 "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
2718 "is|..." - vtable index, method name, creates callable calling COM vtbl
2720 static PyObject *
2721 CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2723 CFuncPtrObject *self;
2724 PyObject *callable;
2725 StgDictObject *dict;
2726 ffi_info *thunk;
2728 if (PyTuple_GET_SIZE(args) == 0)
2729 return GenericCData_new(type, args, kwds);
2731 if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
2732 return CFuncPtr_FromDll(type, args, kwds);
2734 #ifdef MS_WIN32
2735 if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
2736 return CFuncPtr_FromVtblIndex(type, args, kwds);
2737 #endif
2739 if (1 == PyTuple_GET_SIZE(args)
2740 && (PyInt_Check(PyTuple_GET_ITEM(args, 0))
2741 || PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
2742 CDataObject *ob;
2743 void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
2744 if (ptr == NULL)
2745 return NULL;
2746 ob = (CDataObject *)GenericCData_new(type, args, kwds);
2747 *(void **)ob->b_ptr = ptr;
2748 return (PyObject *)ob;
2751 if (!PyArg_ParseTuple(args, "O", &callable))
2752 return NULL;
2753 if (!PyCallable_Check(callable)) {
2754 PyErr_SetString(PyExc_TypeError,
2755 "argument must be callable or integer function address");
2756 return NULL;
2759 /* XXX XXX This would allow to pass additional options. For COM
2760 method *implementations*, we would probably want different
2761 behaviour than in 'normal' callback functions: return a HRESULT if
2762 an exception occurrs in the callback, and print the traceback not
2763 only on the console, but also to OutputDebugString() or something
2764 like that.
2767 if (kwds && PyDict_GetItemString(kwds, "options")) {
2772 dict = PyType_stgdict((PyObject *)type);
2773 /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */
2774 if (!dict || !dict->argtypes) {
2775 PyErr_SetString(PyExc_TypeError,
2776 "cannot construct instance of this class:"
2777 " no argtypes");
2778 return NULL;
2781 /*****************************************************************/
2782 /* The thunk keeps unowned references to callable and dict->argtypes
2783 so we have to keep them alive somewhere else: callable is kept in self,
2784 dict->argtypes is in the type's stgdict.
2786 thunk = AllocFunctionCallback(callable,
2787 dict->argtypes,
2788 dict->restype,
2789 dict->flags & FUNCFLAG_CDECL);
2790 if (!thunk)
2791 return NULL;
2793 self = (CFuncPtrObject *)GenericCData_new(type, args, kwds);
2795 Py_INCREF(callable);
2796 self->callable = callable;
2798 self->thunk = thunk;
2799 *(void **)self->b_ptr = *(void **)thunk;
2801 /* We store ourself in self->b_objects[0], because the whole instance
2802 must be kept alive if stored in a structure field, for example.
2803 Cycle GC to the rescue! And we have a unittest proving that this works
2804 correctly...
2807 Py_INCREF((PyObject *)self); /* for KeepRef */
2808 if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
2809 Py_DECREF((PyObject *)self);
2810 return NULL;
2813 return (PyObject *)self;
2818 _byref consumes a refcount to its argument
2820 static PyObject *
2821 _byref(PyObject *obj)
2823 PyCArgObject *parg;
2824 if (!CDataObject_Check(obj)) {
2825 PyErr_SetString(PyExc_TypeError,
2826 "expected CData instance");
2827 return NULL;
2830 parg = new_CArgObject();
2831 if (parg == NULL) {
2832 Py_DECREF(obj);
2833 return NULL;
2836 parg->tag = 'P';
2837 parg->pffi_type = &ffi_type_pointer;
2838 parg->obj = obj;
2839 parg->value.p = ((CDataObject *)obj)->b_ptr;
2840 return (PyObject *)parg;
2843 static PyObject *
2844 _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
2846 PyObject *v;
2848 if (*pindex < PyTuple_GET_SIZE(inargs)) {
2849 v = PyTuple_GET_ITEM(inargs, *pindex);
2850 ++*pindex;
2851 Py_INCREF(v);
2852 return v;
2854 if (kwds && (v = PyDict_GetItemString(kwds, name))) {
2855 ++*pindex;
2856 Py_INCREF(v);
2857 return v;
2859 if (defval) {
2860 Py_INCREF(defval);
2861 return defval;
2863 /* we can't currently emit a better error message */
2864 if (name)
2865 PyErr_Format(PyExc_TypeError,
2866 "required argument '%s' missing", name);
2867 else
2868 PyErr_Format(PyExc_TypeError,
2869 "not enough arguments");
2870 return NULL;
2874 This function implements higher level functionality plus the ability to call
2875 functions with keyword arguments by looking at parameter flags. parameter
2876 flags is a tuple of 1, 2 or 3-tuples. The first entry in each is an integer
2877 specifying the direction of the data transfer for this parameter - 'in',
2878 'out' or 'inout' (zero means the same as 'in'). The second entry is the
2879 parameter name, and the third is the default value if the parameter is
2880 missing in the function call.
2882 This function builds and returns a new tuple 'callargs' which contains the
2883 parameters to use in the call. Items on this tuple are copied from the
2884 'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
2885 'argtypes' tuple for 'out' parameters. It also calculates numretvals which
2886 is the number of return values for the function, outmask/inoutmask are
2887 bitmasks containing indexes into the callargs tuple specifying which
2888 parameters have to be returned. _build_result builds the return value of the
2889 function.
2891 static PyObject *
2892 _build_callargs(CFuncPtrObject *self, PyObject *argtypes,
2893 PyObject *inargs, PyObject *kwds,
2894 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
2896 PyObject *paramflags = self->paramflags;
2897 PyObject *callargs;
2898 StgDictObject *dict;
2899 int i, len;
2900 int inargs_index = 0;
2901 /* It's a little bit difficult to determine how many arguments the
2902 function call requires/accepts. For simplicity, we count the consumed
2903 args and compare this to the number of supplied args. */
2904 int actual_args;
2906 *poutmask = 0;
2907 *pinoutmask = 0;
2908 *pnumretvals = 0;
2910 /* Trivial cases, where we either return inargs itself, or a slice of it. */
2911 if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
2912 #ifdef MS_WIN32
2913 if (self->index)
2914 return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
2915 #endif
2916 Py_INCREF(inargs);
2917 return inargs;
2920 len = PyTuple_GET_SIZE(argtypes);
2921 callargs = PyTuple_New(len); /* the argument tuple we build */
2922 if (callargs == NULL)
2923 return NULL;
2925 #ifdef MS_WIN32
2926 /* For a COM method, skip the first arg */
2927 if (self->index) {
2928 inargs_index = 1;
2930 #endif
2931 for (i = 0; i < len; ++i) {
2932 PyObject *item = PyTuple_GET_ITEM(paramflags, i);
2933 PyObject *ob;
2934 int flag;
2935 char *name = NULL;
2936 PyObject *defval = NULL;
2938 /* This way seems to be ~2 us faster than the PyArg_ParseTuple
2939 calls below. */
2940 /* We HAVE already checked that the tuple can be parsed with "i|zO", so... */
2941 int tsize = PyTuple_GET_SIZE(item);
2942 flag = PyInt_AS_LONG(PyTuple_GET_ITEM(item, 0));
2943 name = tsize > 1 ? PyString_AS_STRING(PyTuple_GET_ITEM(item, 1)) : NULL;
2944 defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
2946 switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
2947 case PARAMFLAG_FIN | PARAMFLAG_FLCID:
2948 /* ['in', 'lcid'] parameter. Always taken from defval,
2949 if given, else the integer 0. */
2950 if (defval == NULL) {
2951 defval = PyInt_FromLong(0);
2952 if (defval == NULL)
2953 goto error;
2954 } else
2955 Py_INCREF(defval);
2956 PyTuple_SET_ITEM(callargs, i, defval);
2957 break;
2958 case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
2959 *pinoutmask |= (1 << i); /* mark as inout arg */
2960 (*pnumretvals)++;
2961 /* fall through to PARAMFLAG_FIN... */
2962 case 0:
2963 case PARAMFLAG_FIN:
2964 /* 'in' parameter. Copy it from inargs. */
2965 ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
2966 if (ob == NULL)
2967 goto error;
2968 PyTuple_SET_ITEM(callargs, i, ob);
2969 break;
2970 case PARAMFLAG_FOUT:
2971 /* XXX Refactor this code into a separate function. */
2972 /* 'out' parameter.
2973 argtypes[i] must be a POINTER to a c type.
2975 Cannot by supplied in inargs, but a defval will be used
2976 if available. XXX Should we support getting it from kwds?
2978 if (defval) {
2979 /* XXX Using mutable objects as defval will
2980 make the function non-threadsafe, unless we
2981 copy the object in each invocation */
2982 Py_INCREF(defval);
2983 PyTuple_SET_ITEM(callargs, i, defval);
2984 *poutmask |= (1 << i); /* mark as out arg */
2985 (*pnumretvals)++;
2986 break;
2988 ob = PyTuple_GET_ITEM(argtypes, i);
2989 dict = PyType_stgdict(ob);
2990 if (PyString_Check(dict->proto)) {
2991 PyErr_Format(
2992 PyExc_TypeError,
2993 "%s 'out' parameter must be passed as default value",
2994 ((PyTypeObject *)ob)->tp_name);
2995 goto error;
2997 if (ArrayTypeObject_Check(ob))
2998 ob = PyObject_CallObject(ob, NULL);
2999 else
3000 /* Create an instance of the pointed-to type */
3001 ob = PyObject_CallObject(dict->proto, NULL);
3003 XXX Is the following correct any longer?
3004 We must not pass a byref() to the array then but
3005 the array instance itself. Then, we cannot retrive
3006 the result from the PyCArgObject.
3008 if (ob == NULL)
3009 goto error;
3010 /* The .from_param call that will ocurr later will pass this
3011 as a byref parameter. */
3012 PyTuple_SET_ITEM(callargs, i, ob);
3013 *poutmask |= (1 << i); /* mark as out arg */
3014 (*pnumretvals)++;
3015 break;
3016 default:
3017 PyErr_Format(PyExc_ValueError,
3018 "paramflag %d not yet implemented", flag);
3019 goto error;
3020 break;
3024 /* We have counted the arguments we have consumed in 'inargs_index'. This
3025 must be the same as len(inargs) + len(kwds), otherwise we have
3026 either too much or not enough arguments. */
3028 actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_Size(kwds) : 0);
3029 if (actual_args != inargs_index) {
3030 /* When we have default values or named parameters, this error
3031 message is misleading. See unittests/test_paramflags.py
3033 PyErr_Format(PyExc_TypeError,
3034 "call takes exactly %d arguments (%d given)",
3035 inargs_index, actual_args);
3036 goto error;
3039 /* outmask is a bitmask containing indexes into callargs. Items at
3040 these indexes contain values to return.
3042 return callargs;
3043 error:
3044 Py_DECREF(callargs);
3045 return NULL;
3048 /* See also:
3049 http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
3052 Build return value of a function.
3054 Consumes the refcount on result and callargs.
3056 static PyObject *
3057 _build_result(PyObject *result, PyObject *callargs,
3058 int outmask, int inoutmask, unsigned int numretvals)
3060 unsigned int i, index;
3061 int bit;
3062 PyObject *tup = NULL;
3064 if (callargs == NULL)
3065 return result;
3066 if (result == NULL || numretvals == 0) {
3067 Py_DECREF(callargs);
3068 return result;
3070 Py_DECREF(result);
3072 /* tup will not be allocated if numretvals == 1 */
3073 /* allocate tuple to hold the result */
3074 if (numretvals > 1) {
3075 tup = PyTuple_New(numretvals);
3076 if (tup == NULL) {
3077 Py_DECREF(callargs);
3078 return NULL;
3082 index = 0;
3083 for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
3084 PyObject *v;
3085 if (bit & inoutmask) {
3086 v = PyTuple_GET_ITEM(callargs, i);
3087 Py_INCREF(v);
3088 if (numretvals == 1) {
3089 Py_DECREF(callargs);
3090 return v;
3092 PyTuple_SET_ITEM(tup, index, v);
3093 index++;
3094 } else if (bit & outmask) {
3095 v = PyTuple_GET_ITEM(callargs, i);
3096 v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL);
3097 if (v == NULL || numretvals == 1) {
3098 Py_DECREF(callargs);
3099 return v;
3101 PyTuple_SET_ITEM(tup, index, v);
3102 index++;
3104 if (index == numretvals)
3105 break;
3108 Py_DECREF(callargs);
3109 return tup;
3112 static PyObject *
3113 CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
3115 PyObject *restype;
3116 PyObject *converters;
3117 PyObject *checker;
3118 PyObject *argtypes;
3119 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3120 PyObject *result;
3121 PyObject *callargs;
3122 PyObject *errcheck;
3123 #ifdef MS_WIN32
3124 IUnknown *piunk = NULL;
3125 #endif
3126 void *pProc = NULL;
3128 int inoutmask;
3129 int outmask;
3130 unsigned int numretvals;
3132 assert(dict); /* if not, it's a bug */
3133 restype = self->restype ? self->restype : dict->restype;
3134 converters = self->converters ? self->converters : dict->converters;
3135 checker = self->checker ? self->checker : dict->checker;
3136 argtypes = self->argtypes ? self->argtypes : dict->argtypes;
3137 /* later, we probably want to have an errcheck field in stgdict */
3138 errcheck = self->errcheck /* ? self->errcheck : dict->errcheck */;
3141 pProc = *(void **)self->b_ptr;
3142 #ifdef MS_WIN32
3143 if (self->index) {
3144 /* It's a COM method */
3145 CDataObject *this;
3146 this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
3147 if (!this) {
3148 PyErr_SetString(PyExc_ValueError,
3149 "native com method call without 'this' parameter");
3150 return NULL;
3152 if (!CDataObject_Check(this)) {
3153 PyErr_SetString(PyExc_TypeError,
3154 "Expected a COM this pointer as first argument");
3155 return NULL;
3157 /* there should be more checks? No, in Python */
3158 /* First arg is an pointer to an interface instance */
3159 if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
3160 PyErr_SetString(PyExc_ValueError,
3161 "NULL COM pointer access");
3162 return NULL;
3164 piunk = *(IUnknown **)this->b_ptr;
3165 if (NULL == piunk->lpVtbl) {
3166 PyErr_SetString(PyExc_ValueError,
3167 "COM method call without VTable");
3168 return NULL;
3170 pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
3172 #endif
3173 callargs = _build_callargs(self, argtypes,
3174 inargs, kwds,
3175 &outmask, &inoutmask, &numretvals);
3176 if (callargs == NULL)
3177 return NULL;
3179 if (converters) {
3180 int required = PyTuple_GET_SIZE(converters);
3181 int actual = PyTuple_GET_SIZE(callargs);
3183 if ((dict->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
3184 /* For cdecl functions, we allow more actual arguments
3185 than the length of the argtypes tuple.
3187 if (required > actual) {
3188 Py_DECREF(callargs);
3189 PyErr_Format(PyExc_TypeError,
3190 "this function takes at least %d argument%s (%d given)",
3191 required,
3192 required == 1 ? "" : "s",
3193 actual);
3194 return NULL;
3196 } else if (required != actual) {
3197 Py_DECREF(callargs);
3198 PyErr_Format(PyExc_TypeError,
3199 "this function takes %d argument%s (%d given)",
3200 required,
3201 required == 1 ? "" : "s",
3202 actual);
3203 return NULL;
3207 result = _CallProc(pProc,
3208 callargs,
3209 #ifdef MS_WIN32
3210 piunk,
3211 self->iid,
3212 #endif
3213 dict->flags,
3214 converters,
3215 restype,
3216 checker);
3217 /* The 'errcheck' protocol */
3218 if (result != NULL && errcheck) {
3219 PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
3220 result,
3221 self,
3222 callargs,
3223 NULL);
3224 /* If the errcheck funtion failed, return NULL.
3225 If the errcheck function returned callargs unchanged,
3226 continue normal processing.
3227 If the errcheck function returned something else,
3228 use that as result.
3230 if (v == NULL || v != callargs) {
3231 Py_DECREF(result);
3232 Py_DECREF(callargs);
3233 return v;
3235 Py_DECREF(v);
3238 return _build_result(result, callargs,
3239 outmask, inoutmask, numretvals);
3242 static int
3243 CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg)
3245 Py_VISIT(self->callable);
3246 Py_VISIT(self->restype);
3247 Py_VISIT(self->checker);
3248 Py_VISIT(self->errcheck);
3249 Py_VISIT(self->argtypes);
3250 Py_VISIT(self->converters);
3251 Py_VISIT(self->paramflags);
3252 return CData_traverse((CDataObject *)self, visit, arg);
3255 static int
3256 CFuncPtr_clear(CFuncPtrObject *self)
3258 Py_CLEAR(self->callable);
3259 Py_CLEAR(self->restype);
3260 Py_CLEAR(self->checker);
3261 Py_CLEAR(self->errcheck);
3262 Py_CLEAR(self->argtypes);
3263 Py_CLEAR(self->converters);
3264 Py_CLEAR(self->paramflags);
3266 if (self->thunk) {
3267 FreeClosure(self->thunk->pcl);
3268 PyMem_Free(self->thunk);
3269 self->thunk = NULL;
3272 return CData_clear((CDataObject *)self);
3275 static void
3276 CFuncPtr_dealloc(CFuncPtrObject *self)
3278 CFuncPtr_clear(self);
3279 self->ob_type->tp_free((PyObject *)self);
3282 static PyObject *
3283 CFuncPtr_repr(CFuncPtrObject *self)
3285 #ifdef MS_WIN32
3286 if (self->index)
3287 return PyString_FromFormat("<COM method offset %d: %s at %p>",
3288 self->index - 0x1000,
3289 self->ob_type->tp_name,
3290 self);
3291 #endif
3292 return PyString_FromFormat("<%s object at %p>",
3293 self->ob_type->tp_name,
3294 self);
3297 PyTypeObject CFuncPtr_Type = {
3298 PyObject_HEAD_INIT(NULL)
3300 "_ctypes.CFuncPtr",
3301 sizeof(CFuncPtrObject), /* tp_basicsize */
3302 0, /* tp_itemsize */
3303 (destructor)CFuncPtr_dealloc, /* tp_dealloc */
3304 0, /* tp_print */
3305 0, /* tp_getattr */
3306 0, /* tp_setattr */
3307 0, /* tp_compare */
3308 (reprfunc)CFuncPtr_repr, /* tp_repr */
3309 0, /* tp_as_number */
3310 0, /* tp_as_sequence */
3311 0, /* tp_as_mapping */
3312 0, /* tp_hash */
3313 (ternaryfunc)CFuncPtr_call, /* tp_call */
3314 0, /* tp_str */
3315 0, /* tp_getattro */
3316 0, /* tp_setattro */
3317 &CData_as_buffer, /* tp_as_buffer */
3318 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3319 "Function Pointer", /* tp_doc */
3320 (traverseproc)CFuncPtr_traverse, /* tp_traverse */
3321 (inquiry)CFuncPtr_clear, /* tp_clear */
3322 0, /* tp_richcompare */
3323 0, /* tp_weaklistoffset */
3324 0, /* tp_iter */
3325 0, /* tp_iternext */
3326 0, /* tp_methods */
3327 0, /* tp_members */
3328 CFuncPtr_getsets, /* tp_getset */
3329 0, /* tp_base */
3330 0, /* tp_dict */
3331 0, /* tp_descr_get */
3332 0, /* tp_descr_set */
3333 0, /* tp_dictoffset */
3334 0, /* tp_init */
3335 0, /* tp_alloc */
3336 CFuncPtr_new, /* tp_new */
3337 0, /* tp_free */
3340 /*****************************************************************/
3342 Struct_Type
3344 static int
3345 IBUG(char *msg)
3347 PyErr_Format(PyExc_RuntimeError,
3348 "inconsistent state in CDataObject (%s)", msg);
3349 return -1;
3352 static PyObject *
3353 Struct_as_parameter(CDataObject *self)
3355 PyCArgObject *parg;
3356 StgDictObject *stgdict;
3358 parg = new_CArgObject();
3359 if (parg == NULL)
3360 return NULL;
3362 parg->tag = 'V';
3363 stgdict = PyObject_stgdict((PyObject *)self);
3364 parg->pffi_type = &stgdict->ffi_type_pointer;
3365 /* For structure parameters (by value), parg->value doesn't contain the structure
3366 data itself, instead parg->value.p *points* to the structure's data
3367 See also _ctypes.c, function _call_function_pointer().
3369 parg->value.p = self->b_ptr;
3370 parg->size = self->b_size;
3371 Py_INCREF(self);
3372 parg->obj = (PyObject *)self;
3373 return (PyObject *)parg;
3376 static int
3377 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
3379 int i;
3380 PyObject *fields;
3382 /* Optimization possible: Store the attribute names _fields_[x][0]
3383 * in C accessible fields somewhere ?
3386 /* Check this code again for correctness! */
3388 if (!PyTuple_Check(args)) {
3389 PyErr_SetString(PyExc_TypeError,
3390 "args not a tuple?");
3391 return -1;
3393 if (PyTuple_GET_SIZE(args)) {
3394 fields = PyObject_GetAttrString(self, "_fields_");
3395 if (!fields) {
3396 PyErr_Clear();
3397 fields = PyTuple_New(0);
3398 if (!fields)
3399 return -1;
3402 if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
3403 Py_DECREF(fields);
3404 PyErr_SetString(PyExc_ValueError,
3405 "too many initializers");
3406 return -1;
3409 for (i = 0; i < PyTuple_GET_SIZE(args); ++i) {
3410 PyObject *pair = PySequence_GetItem(fields, i);
3411 PyObject *name;
3412 PyObject *val;
3413 if (!pair) {
3414 Py_DECREF(fields);
3415 return IBUG("_fields_[i] failed");
3418 name = PySequence_GetItem(pair, 0);
3419 if (!name) {
3420 Py_DECREF(pair);
3421 Py_DECREF(fields);
3422 return IBUG("_fields_[i][0] failed");
3425 val = PyTuple_GET_ITEM(args, i);
3426 if (-1 == PyObject_SetAttr(self, name, val)) {
3427 Py_DECREF(pair);
3428 Py_DECREF(name);
3429 Py_DECREF(fields);
3430 return -1;
3433 Py_DECREF(name);
3434 Py_DECREF(pair);
3436 Py_DECREF(fields);
3439 if (kwds) {
3440 PyObject *key, *value;
3441 Py_ssize_t pos = 0;
3442 while(PyDict_Next(kwds, &pos, &key, &value)) {
3443 if (-1 == PyObject_SetAttr(self, key, value))
3444 return -1;
3447 return 0;
3450 static PyGetSetDef Struct_getsets[] = {
3451 { "_as_parameter_", (getter)Struct_as_parameter, NULL,
3452 "return a magic value so that this can be converted to a C parameter (readonly)",
3453 NULL },
3454 { NULL, NULL }
3457 static PyTypeObject Struct_Type = {
3458 PyObject_HEAD_INIT(NULL)
3460 "_ctypes.Structure",
3461 sizeof(CDataObject), /* tp_basicsize */
3462 0, /* tp_itemsize */
3463 0, /* tp_dealloc */
3464 0, /* tp_print */
3465 0, /* tp_getattr */
3466 0, /* tp_setattr */
3467 0, /* tp_compare */
3468 0, /* tp_repr */
3469 0, /* tp_as_number */
3470 0, /* tp_as_sequence */
3471 0, /* tp_as_mapping */
3472 0, /* tp_hash */
3473 0, /* tp_call */
3474 0, /* tp_str */
3475 0, /* tp_getattro */
3476 0, /* tp_setattro */
3477 &CData_as_buffer, /* tp_as_buffer */
3478 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3479 "Structure base class", /* tp_doc */
3480 (traverseproc)CData_traverse, /* tp_traverse */
3481 (inquiry)CData_clear, /* tp_clear */
3482 0, /* tp_richcompare */
3483 0, /* tp_weaklistoffset */
3484 0, /* tp_iter */
3485 0, /* tp_iternext */
3486 0, /* tp_methods */
3487 0, /* tp_members */
3488 Struct_getsets, /* tp_getset */
3489 0, /* tp_base */
3490 0, /* tp_dict */
3491 0, /* tp_descr_get */
3492 0, /* tp_descr_set */
3493 0, /* tp_dictoffset */
3494 Struct_init, /* tp_init */
3495 0, /* tp_alloc */
3496 GenericCData_new, /* tp_new */
3497 0, /* tp_free */
3500 static PyTypeObject Union_Type = {
3501 PyObject_HEAD_INIT(NULL)
3503 "_ctypes.Union",
3504 sizeof(CDataObject), /* tp_basicsize */
3505 0, /* tp_itemsize */
3506 0, /* tp_dealloc */
3507 0, /* tp_print */
3508 0, /* tp_getattr */
3509 0, /* tp_setattr */
3510 0, /* tp_compare */
3511 0, /* tp_repr */
3512 0, /* tp_as_number */
3513 0, /* tp_as_sequence */
3514 0, /* tp_as_mapping */
3515 0, /* tp_hash */
3516 0, /* tp_call */
3517 0, /* tp_str */
3518 0, /* tp_getattro */
3519 0, /* tp_setattro */
3520 &CData_as_buffer, /* tp_as_buffer */
3521 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3522 "Union base class", /* tp_doc */
3523 (traverseproc)CData_traverse, /* tp_traverse */
3524 (inquiry)CData_clear, /* tp_clear */
3525 0, /* tp_richcompare */
3526 0, /* tp_weaklistoffset */
3527 0, /* tp_iter */
3528 0, /* tp_iternext */
3529 0, /* tp_methods */
3530 0, /* tp_members */
3531 Struct_getsets, /* tp_getset */
3532 0, /* tp_base */
3533 0, /* tp_dict */
3534 0, /* tp_descr_get */
3535 0, /* tp_descr_set */
3536 0, /* tp_dictoffset */
3537 Struct_init, /* tp_init */
3538 0, /* tp_alloc */
3539 GenericCData_new, /* tp_new */
3540 0, /* tp_free */
3544 /******************************************************************/
3546 Array_Type
3548 static int
3549 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
3551 int i;
3552 int n;
3554 if (!PyTuple_Check(args)) {
3555 PyErr_SetString(PyExc_TypeError,
3556 "args not a tuple?");
3557 return -1;
3559 n = PyTuple_GET_SIZE(args);
3560 for (i = 0; i < n; ++i) {
3561 PyObject *v;
3562 v = PyTuple_GET_ITEM(args, i);
3563 if (-1 == PySequence_SetItem((PyObject *)self, i, v))
3564 return -1;
3566 return 0;
3569 static PyObject *
3570 Array_item(PyObject *_self, Py_ssize_t index)
3572 CDataObject *self = (CDataObject *)_self;
3573 int offset, size;
3574 StgDictObject *stgdict;
3577 if (index < 0 || index >= self->b_length) {
3578 PyErr_SetString(PyExc_IndexError,
3579 "invalid index");
3580 return NULL;
3583 stgdict = PyObject_stgdict((PyObject *)self);
3584 assert(stgdict);
3585 /* Would it be clearer if we got the item size from
3586 stgdict->proto's stgdict?
3588 size = stgdict->size / stgdict->length;
3589 offset = index * size;
3591 return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
3592 index, size, self->b_ptr + offset);
3595 static PyObject *
3596 Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
3598 CDataObject *self = (CDataObject *)_self;
3599 StgDictObject *stgdict, *itemdict;
3600 PyObject *proto;
3601 PyListObject *np;
3602 Py_ssize_t i, len;
3604 if (ilow < 0)
3605 ilow = 0;
3606 else if (ilow > self->b_length)
3607 ilow = self->b_length;
3608 if (ihigh < ilow)
3609 ihigh = ilow;
3610 else if (ihigh > self->b_length)
3611 ihigh = self->b_length;
3612 len = ihigh - ilow;
3614 stgdict = PyObject_stgdict((PyObject *)self);
3615 proto = stgdict->proto;
3616 itemdict = PyType_stgdict(proto);
3617 if (itemdict->getfunc == getentry("c")->getfunc) {
3618 char *ptr = (char *)self->b_ptr;
3619 return PyString_FromStringAndSize(ptr + ilow, len);
3620 #ifdef CTYPES_UNICODE
3621 } else if (itemdict->getfunc == getentry("u")->getfunc) {
3622 wchar_t *ptr = (wchar_t *)self->b_ptr;
3623 return PyUnicode_FromWideChar(ptr + ilow, len);
3624 #endif
3627 np = (PyListObject *) PyList_New(len);
3628 if (np == NULL)
3629 return NULL;
3631 for (i = 0; i < len; i++) {
3632 PyObject *v = Array_item(_self, i+ilow);
3633 PyList_SET_ITEM(np, i, v);
3635 return (PyObject *)np;
3638 static int
3639 Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
3641 CDataObject *self = (CDataObject *)_self;
3642 int size, offset;
3643 StgDictObject *stgdict;
3644 char *ptr;
3646 if (value == NULL) {
3647 PyErr_SetString(PyExc_TypeError,
3648 "Array does not support item deletion");
3649 return -1;
3652 stgdict = PyObject_stgdict((PyObject *)self);
3653 if (index < 0 || index >= stgdict->length) {
3654 PyErr_SetString(PyExc_IndexError,
3655 "invalid index");
3656 return -1;
3658 size = stgdict->size / stgdict->length;
3659 offset = index * size;
3660 ptr = self->b_ptr + offset;
3662 return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
3663 index, size, ptr);
3666 static int
3667 Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
3669 CDataObject *self = (CDataObject *)_self;
3670 int i, len;
3672 if (value == NULL) {
3673 PyErr_SetString(PyExc_TypeError,
3674 "Array does not support item deletion");
3675 return -1;
3678 if (ilow < 0)
3679 ilow = 0;
3680 else if (ilow > self->b_length)
3681 ilow = self->b_length;
3682 if (ihigh < 0)
3683 ihigh = 0;
3684 if (ihigh < ilow)
3685 ihigh = ilow;
3686 else if (ihigh > self->b_length)
3687 ihigh = self->b_length;
3689 len = PySequence_Length(value);
3690 if (len != ihigh - ilow) {
3691 PyErr_SetString(PyExc_ValueError,
3692 "Can only assign sequence of same size");
3693 return -1;
3695 for (i = 0; i < len; i++) {
3696 PyObject *item = PySequence_GetItem(value, i);
3697 int result;
3698 if (item == NULL)
3699 return -1;
3700 result = Array_ass_item(_self, i+ilow, item);
3701 Py_DECREF(item);
3702 if (result == -1)
3703 return -1;
3705 return 0;
3708 static Py_ssize_t
3709 Array_length(PyObject *_self)
3711 CDataObject *self = (CDataObject *)_self;
3712 return self->b_length;
3715 static PySequenceMethods Array_as_sequence = {
3716 Array_length, /* sq_length; */
3717 0, /* sq_concat; */
3718 0, /* sq_repeat; */
3719 Array_item, /* sq_item; */
3720 Array_slice, /* sq_slice; */
3721 Array_ass_item, /* sq_ass_item; */
3722 Array_ass_slice, /* sq_ass_slice; */
3723 0, /* sq_contains; */
3725 0, /* sq_inplace_concat; */
3726 0, /* sq_inplace_repeat; */
3729 static PyObject *
3730 Array_as_parameter(CDataObject *self)
3732 PyCArgObject *p = new_CArgObject();
3733 if (p == NULL)
3734 return NULL;
3735 p->tag = 'P';
3736 p->pffi_type = &ffi_type_pointer;
3737 p->value.p = (char *)self->b_ptr;
3738 Py_INCREF(self);
3739 p->obj = (PyObject *)self;
3740 return (PyObject *)p;
3743 static PyGetSetDef Array_getsets[] = {
3744 { "_as_parameter_", (getter)Array_as_parameter,
3745 (setter)NULL, "convert to a parameter", NULL },
3746 { NULL },
3749 PyTypeObject Array_Type = {
3750 PyObject_HEAD_INIT(NULL)
3752 "_ctypes.Array",
3753 sizeof(CDataObject), /* tp_basicsize */
3754 0, /* tp_itemsize */
3755 0, /* tp_dealloc */
3756 0, /* tp_print */
3757 0, /* tp_getattr */
3758 0, /* tp_setattr */
3759 0, /* tp_compare */
3760 0, /* tp_repr */
3761 0, /* tp_as_number */
3762 &Array_as_sequence, /* tp_as_sequence */
3763 0, /* tp_as_mapping */
3764 0, /* tp_hash */
3765 0, /* tp_call */
3766 0, /* tp_str */
3767 0, /* tp_getattro */
3768 0, /* tp_setattro */
3769 &CData_as_buffer, /* tp_as_buffer */
3770 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
3771 "XXX to be provided", /* tp_doc */
3772 (traverseproc)CData_traverse, /* tp_traverse */
3773 (inquiry)CData_clear, /* tp_clear */
3774 0, /* tp_richcompare */
3775 0, /* tp_weaklistoffset */
3776 0, /* tp_iter */
3777 0, /* tp_iternext */
3778 0, /* tp_methods */
3779 0, /* tp_members */
3780 Array_getsets, /* tp_getset */
3781 0, /* tp_base */
3782 0, /* tp_dict */
3783 0, /* tp_descr_get */
3784 0, /* tp_descr_set */
3785 0, /* tp_dictoffset */
3786 (initproc)Array_init, /* tp_init */
3787 0, /* tp_alloc */
3788 GenericCData_new, /* tp_new */
3789 0, /* tp_free */
3792 PyObject *
3793 CreateArrayType(PyObject *itemtype, Py_ssize_t length)
3795 static PyObject *cache;
3796 PyObject *key;
3797 PyObject *result;
3798 char name[256];
3800 if (cache == NULL) {
3801 cache = PyDict_New();
3802 if (cache == NULL)
3803 return NULL;
3805 #if (PY_VERSION_HEX < 0x02050000)
3806 key = Py_BuildValue("(Oi)", itemtype, length);
3807 #else
3808 key = Py_BuildValue("(On)", itemtype, length);
3809 #endif
3810 if (!key)
3811 return NULL;
3812 result = PyDict_GetItem(cache, key);
3813 if (result) {
3814 Py_INCREF(result);
3815 Py_DECREF(key);
3816 return result;
3819 if (!PyType_Check(itemtype)) {
3820 PyErr_SetString(PyExc_TypeError,
3821 "Expected a type object");
3822 return NULL;
3824 #ifdef MS_WIN64
3825 sprintf(name, "%.200s_Array_%Id",
3826 ((PyTypeObject *)itemtype)->tp_name, length);
3827 #else
3828 sprintf(name, "%.200s_Array_%ld",
3829 ((PyTypeObject *)itemtype)->tp_name, (long)length);
3830 #endif
3832 result = PyObject_CallFunction((PyObject *)&ArrayType_Type,
3833 #if (PY_VERSION_HEX < 0x02050000)
3834 "s(O){s:i,s:O}",
3835 #else
3836 "s(O){s:n,s:O}",
3837 #endif
3838 name,
3839 &Array_Type,
3840 "_length_",
3841 length,
3842 "_type_",
3843 itemtype
3845 if (!result)
3846 return NULL;
3847 PyDict_SetItem(cache, key, result);
3848 Py_DECREF(key);
3849 return result;
3853 /******************************************************************/
3855 Simple_Type
3858 static int
3859 Simple_set_value(CDataObject *self, PyObject *value)
3861 PyObject *result;
3862 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3864 assert(dict->setfunc);
3865 result = dict->setfunc(self->b_ptr, value, dict->size);
3866 if (!result)
3867 return -1;
3869 /* consumes the refcount the setfunc returns */
3870 return KeepRef(self, 0, result);
3873 static int
3874 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
3876 PyObject *value = NULL;
3877 if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
3878 return -1;
3879 if (value)
3880 return Simple_set_value(self, value);
3881 return 0;
3884 static PyObject *
3885 Simple_get_value(CDataObject *self)
3887 StgDictObject *dict;
3888 dict = PyObject_stgdict((PyObject *)self);
3889 assert(dict->getfunc);
3890 dict = PyObject_stgdict((PyObject *)self);
3891 return dict->getfunc(self->b_ptr, self->b_size);
3894 static PyObject *
3895 Simple_as_parameter(CDataObject *self)
3897 StgDictObject *dict = PyObject_stgdict((PyObject *)self);
3898 char *fmt = PyString_AsString(dict->proto);
3899 PyCArgObject *parg;
3900 struct fielddesc *fd;
3902 fd = getentry(fmt);
3903 assert(fd);
3905 parg = new_CArgObject();
3906 if (parg == NULL)
3907 return NULL;
3909 parg->tag = fmt[0];
3910 parg->pffi_type = fd->pffi_type;
3911 Py_INCREF(self);
3912 parg->obj = (PyObject *)self;
3913 memcpy(&parg->value, self->b_ptr, self->b_size);
3914 return (PyObject *)parg;
3917 static PyGetSetDef Simple_getsets[] = {
3918 { "value", (getter)Simple_get_value, (setter)Simple_set_value,
3919 "current value", NULL },
3920 { "_as_parameter_", (getter)Simple_as_parameter, NULL,
3921 "return a magic value so that this can be converted to a C parameter (readonly)",
3922 NULL },
3923 { NULL, NULL }
3926 static PyObject *
3927 Simple_from_outparm(PyObject *self, PyObject *args)
3929 if (IsSimpleSubType((PyObject *)self->ob_type)) {
3930 Py_INCREF(self);
3931 return self;
3933 /* call stgdict->getfunc */
3934 return Simple_get_value((CDataObject *)self);
3937 static PyMethodDef Simple_methods[] = {
3938 { "__ctypes_from_outparam__", Simple_from_outparm, METH_NOARGS, },
3939 { NULL, NULL },
3942 static int Simple_nonzero(CDataObject *self)
3944 return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
3947 static PyNumberMethods Simple_as_number = {
3948 0, /* nb_add */
3949 0, /* nb_subtract */
3950 0, /* nb_multiply */
3951 0, /* nb_divide */
3952 0, /* nb_remainder */
3953 0, /* nb_divmod */
3954 0, /* nb_power */
3955 0, /* nb_negative */
3956 0, /* nb_positive */
3957 0, /* nb_absolute */
3958 (inquiry)Simple_nonzero, /* nb_nonzero */
3961 #if (PY_VERSION_HEX < 0x02040000)
3962 /* Only in Python 2.4 and up */
3963 static PyObject *
3964 PyTuple_Pack(int n, ...)
3966 int i;
3967 PyObject *o;
3968 PyObject *result;
3969 PyObject **items;
3970 va_list vargs;
3972 va_start(vargs, n);
3973 result = PyTuple_New(n);
3974 if (result == NULL)
3975 return NULL;
3976 items = ((PyTupleObject *)result)->ob_item;
3977 for (i = 0; i < n; i++) {
3978 o = va_arg(vargs, PyObject *);
3979 Py_INCREF(o);
3980 items[i] = o;
3982 va_end(vargs);
3983 return result;
3985 #endif
3987 /* "%s(%s)" % (self.__class__.__name__, self.value) */
3988 static PyObject *
3989 Simple_repr(CDataObject *self)
3991 PyObject *val, *name, *args, *result;
3992 static PyObject *format;
3994 if (self->ob_type->tp_base != &Simple_Type) {
3995 return PyString_FromFormat("<%s object at %p>",
3996 self->ob_type->tp_name, self);
3999 if (format == NULL) {
4000 format = PyString_FromString("%s(%r)");
4001 if (format == NULL)
4002 return NULL;
4005 val = Simple_get_value(self);
4006 if (val == NULL)
4007 return NULL;
4009 name = PyString_FromString(self->ob_type->tp_name);
4010 if (name == NULL) {
4011 Py_DECREF(val);
4012 return NULL;
4015 args = PyTuple_Pack(2, name, val);
4016 Py_DECREF(name);
4017 Py_DECREF(val);
4018 if (args == NULL)
4019 return NULL;
4021 result = PyString_Format(format, args);
4022 Py_DECREF(args);
4023 return result;
4026 static PyTypeObject Simple_Type = {
4027 PyObject_HEAD_INIT(NULL)
4029 "_ctypes._SimpleCData",
4030 sizeof(CDataObject), /* tp_basicsize */
4031 0, /* tp_itemsize */
4032 0, /* tp_dealloc */
4033 0, /* tp_print */
4034 0, /* tp_getattr */
4035 0, /* tp_setattr */
4036 0, /* tp_compare */
4037 (reprfunc)&Simple_repr, /* tp_repr */
4038 &Simple_as_number, /* tp_as_number */
4039 0, /* tp_as_sequence */
4040 0, /* tp_as_mapping */
4041 0, /* tp_hash */
4042 0, /* tp_call */
4043 0, /* tp_str */
4044 0, /* tp_getattro */
4045 0, /* tp_setattro */
4046 &CData_as_buffer, /* tp_as_buffer */
4047 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4048 "XXX to be provided", /* tp_doc */
4049 (traverseproc)CData_traverse, /* tp_traverse */
4050 (inquiry)CData_clear, /* tp_clear */
4051 0, /* tp_richcompare */
4052 0, /* tp_weaklistoffset */
4053 0, /* tp_iter */
4054 0, /* tp_iternext */
4055 Simple_methods, /* tp_methods */
4056 0, /* tp_members */
4057 Simple_getsets, /* tp_getset */
4058 0, /* tp_base */
4059 0, /* tp_dict */
4060 0, /* tp_descr_get */
4061 0, /* tp_descr_set */
4062 0, /* tp_dictoffset */
4063 (initproc)Simple_init, /* tp_init */
4064 0, /* tp_alloc */
4065 GenericCData_new, /* tp_new */
4066 0, /* tp_free */
4069 /******************************************************************/
4071 Pointer_Type
4073 static PyObject *
4074 Pointer_item(PyObject *_self, Py_ssize_t index)
4076 CDataObject *self = (CDataObject *)_self;
4077 int size;
4078 Py_ssize_t offset;
4079 StgDictObject *stgdict, *itemdict;
4080 PyObject *proto;
4082 if (*(void **)self->b_ptr == NULL) {
4083 PyErr_SetString(PyExc_ValueError,
4084 "NULL pointer access");
4085 return NULL;
4088 stgdict = PyObject_stgdict((PyObject *)self);
4089 assert(stgdict);
4090 assert(stgdict->proto);
4092 proto = stgdict->proto;
4093 /* XXXXXX MAKE SURE PROTO IS NOT NULL! */
4094 itemdict = PyType_stgdict(proto);
4095 size = itemdict->size;
4096 offset = index * itemdict->size;
4098 return CData_get(proto, stgdict->getfunc, (PyObject *)self,
4099 index, size, (*(char **)self->b_ptr) + offset);
4102 static int
4103 Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
4105 CDataObject *self = (CDataObject *)_self;
4106 int size;
4107 Py_ssize_t offset;
4108 StgDictObject *stgdict, *itemdict;
4109 PyObject *proto;
4111 if (value == NULL) {
4112 PyErr_SetString(PyExc_TypeError,
4113 "Pointer does not support item deletion");
4114 return -1;
4117 if (*(void **)self->b_ptr == NULL) {
4118 PyErr_SetString(PyExc_ValueError,
4119 "NULL pointer access");
4120 return -1;
4123 stgdict = PyObject_stgdict((PyObject *)self);
4124 assert(stgdict);
4125 assert(stgdict->proto);
4127 proto = stgdict->proto;
4128 /* XXXXXX MAKE SURE PROTO IS NOT NULL! */
4129 itemdict = PyType_stgdict(proto);
4130 size = itemdict->size;
4131 offset = index * itemdict->size;
4133 return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
4134 index, size, (*(char **)self->b_ptr) + offset);
4137 static PyObject *
4138 Pointer_get_contents(CDataObject *self, void *closure)
4140 StgDictObject *stgdict;
4142 if (*(void **)self->b_ptr == NULL) {
4143 PyErr_SetString(PyExc_ValueError,
4144 "NULL pointer access");
4145 return NULL;
4148 stgdict = PyObject_stgdict((PyObject *)self);
4149 assert(stgdict);
4150 return CData_FromBaseObj(stgdict->proto,
4151 (PyObject *)self, 0,
4152 *(void **)self->b_ptr);
4155 static int
4156 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
4158 StgDictObject *stgdict;
4159 CDataObject *dst;
4160 PyObject *keep;
4162 if (value == NULL) {
4163 PyErr_SetString(PyExc_TypeError,
4164 "Pointer does not support item deletion");
4165 return -1;
4167 stgdict = PyObject_stgdict((PyObject *)self);
4168 /* should have been catched in Pointer_new() */
4169 assert(stgdict->proto);
4170 if (!CDataObject_Check(value)
4171 || 0 == PyObject_IsInstance(value, stgdict->proto)) {
4172 /* XXX PyObject_IsInstance could return -1! */
4173 PyErr_Format(PyExc_TypeError,
4174 "expected %s instead of %s",
4175 ((PyTypeObject *)(stgdict->proto))->tp_name,
4176 value->ob_type->tp_name);
4177 return -1;
4180 dst = (CDataObject *)value;
4181 *(void **)self->b_ptr = dst->b_ptr;
4184 A Pointer instance must keep a the value it points to alive. So, a
4185 pointer instance has b_length set to 2 instead of 1, and we set
4186 'value' itself as the second item of the b_objects list, additionally.
4188 Py_INCREF(value);
4189 if (-1 == KeepRef(self, 1, value))
4190 return -1;
4192 keep = GetKeepedObjects(dst);
4193 Py_INCREF(keep);
4194 return KeepRef(self, 0, keep);
4197 static PyObject *
4198 Pointer_as_parameter(CDataObject *self)
4200 PyCArgObject *parg;
4202 parg = new_CArgObject();
4203 if (parg == NULL)
4204 return NULL;
4206 parg->tag = 'P';
4207 parg->pffi_type = &ffi_type_pointer;
4208 Py_INCREF(self);
4209 parg->obj = (PyObject *)self;
4210 parg->value.p = *(void **)self->b_ptr;
4211 return (PyObject *)parg;
4214 static PyGetSetDef Pointer_getsets[] = {
4215 { "contents", (getter)Pointer_get_contents,
4216 (setter)Pointer_set_contents,
4217 "the object this pointer points to (read-write)", NULL },
4218 { "_as_parameter_", (getter)Pointer_as_parameter, NULL,
4219 "return a magic value so that this can be converted to a C parameter (readonly)",
4220 NULL },
4221 { NULL, NULL }
4224 static int
4225 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
4227 PyObject *value = NULL;
4229 if (!PyArg_ParseTuple(args, "|O:POINTER", &value))
4230 return -1;
4231 if (value == NULL)
4232 return 0;
4233 return Pointer_set_contents(self, value, NULL);
4236 static PyObject *
4237 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
4239 StgDictObject *dict = PyType_stgdict((PyObject *)type);
4240 if (!dict || !dict->proto) {
4241 PyErr_SetString(PyExc_TypeError,
4242 "Cannot create instance: has no _type_");
4243 return NULL;
4245 return GenericCData_new(type, args, kw);
4248 static PyObject *
4249 Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
4251 CDataObject *self = (CDataObject *)_self;
4252 PyListObject *np;
4253 StgDictObject *stgdict, *itemdict;
4254 PyObject *proto;
4255 Py_ssize_t i, len;
4257 if (ilow < 0)
4258 ilow = 0;
4259 if (ihigh < ilow)
4260 ihigh = ilow;
4261 len = ihigh - ilow;
4263 stgdict = PyObject_stgdict((PyObject *)self);
4264 proto = stgdict->proto;
4265 itemdict = PyType_stgdict(proto);
4266 if (itemdict->getfunc == getentry("c")->getfunc) {
4267 char *ptr = *(char **)self->b_ptr;
4268 return PyString_FromStringAndSize(ptr + ilow, len);
4269 #ifdef CTYPES_UNICODE
4270 } else if (itemdict->getfunc == getentry("u")->getfunc) {
4271 wchar_t *ptr = *(wchar_t **)self->b_ptr;
4272 return PyUnicode_FromWideChar(ptr + ilow, len);
4273 #endif
4276 np = (PyListObject *) PyList_New(len);
4277 if (np == NULL)
4278 return NULL;
4280 for (i = 0; i < len; i++) {
4281 PyObject *v = Pointer_item(_self, i+ilow);
4282 PyList_SET_ITEM(np, i, v);
4284 return (PyObject *)np;
4287 static PySequenceMethods Pointer_as_sequence = {
4288 0, /* inquiry sq_length; */
4289 0, /* binaryfunc sq_concat; */
4290 0, /* intargfunc sq_repeat; */
4291 Pointer_item, /* intargfunc sq_item; */
4292 Pointer_slice, /* intintargfunc sq_slice; */
4293 Pointer_ass_item, /* intobjargproc sq_ass_item; */
4294 0, /* intintobjargproc sq_ass_slice; */
4295 0, /* objobjproc sq_contains; */
4296 /* Added in release 2.0 */
4297 0, /* binaryfunc sq_inplace_concat; */
4298 0, /* intargfunc sq_inplace_repeat; */
4301 static int
4302 Pointer_nonzero(CDataObject *self)
4304 return *(void **)self->b_ptr != NULL;
4307 static PyNumberMethods Pointer_as_number = {
4308 0, /* nb_add */
4309 0, /* nb_subtract */
4310 0, /* nb_multiply */
4311 0, /* nb_divide */
4312 0, /* nb_remainder */
4313 0, /* nb_divmod */
4314 0, /* nb_power */
4315 0, /* nb_negative */
4316 0, /* nb_positive */
4317 0, /* nb_absolute */
4318 (inquiry)Pointer_nonzero, /* nb_nonzero */
4321 PyTypeObject Pointer_Type = {
4322 PyObject_HEAD_INIT(NULL)
4324 "_ctypes._Pointer",
4325 sizeof(CDataObject), /* tp_basicsize */
4326 0, /* tp_itemsize */
4327 0, /* tp_dealloc */
4328 0, /* tp_print */
4329 0, /* tp_getattr */
4330 0, /* tp_setattr */
4331 0, /* tp_compare */
4332 0, /* tp_repr */
4333 &Pointer_as_number, /* tp_as_number */
4334 &Pointer_as_sequence, /* tp_as_sequence */
4335 0, /* tp_as_mapping */
4336 0, /* tp_hash */
4337 0, /* tp_call */
4338 0, /* tp_str */
4339 0, /* tp_getattro */
4340 0, /* tp_setattro */
4341 &CData_as_buffer, /* tp_as_buffer */
4342 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
4343 "XXX to be provided", /* tp_doc */
4344 (traverseproc)CData_traverse, /* tp_traverse */
4345 (inquiry)CData_clear, /* tp_clear */
4346 0, /* tp_richcompare */
4347 0, /* tp_weaklistoffset */
4348 0, /* tp_iter */
4349 0, /* tp_iternext */
4350 0, /* tp_methods */
4351 0, /* tp_members */
4352 Pointer_getsets, /* tp_getset */
4353 0, /* tp_base */
4354 0, /* tp_dict */
4355 0, /* tp_descr_get */
4356 0, /* tp_descr_set */
4357 0, /* tp_dictoffset */
4358 (initproc)Pointer_init, /* tp_init */
4359 0, /* tp_alloc */
4360 Pointer_new, /* tp_new */
4361 0, /* tp_free */
4365 /******************************************************************/
4367 * Module initialization.
4370 static char *module_docs =
4371 "Create and manipulate C compatible data types in Python.";
4373 #ifdef MS_WIN32
4375 static char comerror_doc[] = "Raised when a COM method call failed.";
4377 static PyObject *
4378 comerror_str(PyObject *ignored, PyObject *self)
4380 PyObject *args = PyObject_GetAttrString(self, "args");
4381 PyObject *result;
4382 if (args == NULL)
4383 return NULL;
4384 result = PyObject_Str(args);
4385 Py_DECREF(args);
4386 return result;
4389 static PyObject *
4390 comerror_init(PyObject *self, PyObject *args)
4392 PyObject *hresult, *text, *details;
4393 PyObject *a;
4394 int status;
4396 if (!PyArg_ParseTuple(args, "OOOO:COMError", &self, &hresult, &text, &details))
4397 return NULL;
4399 a = PySequence_GetSlice(args, 1, PySequence_Size(args));
4400 if (!a)
4401 return NULL;
4402 status = PyObject_SetAttrString(self, "args", a);
4403 Py_DECREF(a);
4404 if (status < 0)
4405 return NULL;
4407 if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
4408 return NULL;
4410 if (PyObject_SetAttrString(self, "text", text) < 0)
4411 return NULL;
4413 if (PyObject_SetAttrString(self, "details", details) < 0)
4414 return NULL;
4416 Py_INCREF(Py_None);
4417 return Py_None;
4420 static PyMethodDef comerror_methods[] = {
4421 { "__str__", comerror_str, METH_O },
4422 { "__init__", comerror_init, METH_VARARGS },
4423 { NULL, NULL },
4426 PyObject *COMError;
4428 static int
4429 create_comerror(void)
4431 PyObject *dict = PyDict_New();
4432 PyMethodDef *methods = comerror_methods;
4433 PyObject *s;
4434 int status;
4436 ComError = PyErr_NewException("_ctypes.COMError",
4437 NULL,
4438 dict);
4439 if (ComError == NULL)
4440 return -1;
4441 while (methods->ml_name) {
4442 /* get a wrapper for the built-in function */
4443 PyObject *func = PyCFunction_New(methods, NULL);
4444 PyObject *meth;
4445 if (func == NULL)
4446 return -1;
4447 meth = PyMethod_New(func, NULL, ComError);
4448 Py_DECREF(func);
4449 if (meth == NULL)
4450 return -1;
4451 PyDict_SetItemString(dict, methods->ml_name, meth);
4452 Py_DECREF(meth);
4453 ++methods;
4455 Py_INCREF(ComError);
4456 s = PyString_FromString(comerror_doc);
4457 if (s == NULL)
4458 return -1;
4459 status = PyDict_SetItemString(dict, "__doc__", s);
4460 Py_DECREF(s);
4461 return status;
4464 #endif
4466 static PyObject *
4467 string_at(const char *ptr, Py_ssize_t size)
4469 if (size == 0)
4470 return PyString_FromString(ptr);
4471 return PyString_FromStringAndSize(ptr, size);
4474 static int
4475 cast_check_pointertype(PyObject *arg)
4477 StgDictObject *dict;
4479 if (PointerTypeObject_Check(arg))
4480 return 1;
4481 if (CFuncPtrTypeObject_Check(arg))
4482 return 1;
4483 dict = PyType_stgdict(arg);
4484 if (dict) {
4485 if (PyString_Check(dict->proto)
4486 && (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
4487 /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
4488 return 1;
4491 PyErr_Format(PyExc_TypeError,
4492 "cast() argument 2 must be a pointer type, not %s",
4493 PyType_Check(arg)
4494 ? ((PyTypeObject *)arg)->tp_name
4495 : arg->ob_type->tp_name);
4496 return 0;
4499 static PyObject *
4500 cast(void *ptr, PyObject *src, PyObject *ctype)
4502 CDataObject *result;
4503 if (0 == cast_check_pointertype(ctype))
4504 return NULL;
4505 result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
4506 if (result == NULL)
4507 return NULL;
4510 The casted objects '_objects' member:
4512 It must certainly contain the source objects one.
4513 It must contain the source object itself.
4515 if (CDataObject_Check(src)) {
4516 CDataObject *obj = (CDataObject *)src;
4517 /* CData_GetContainer will initialize src.b_objects, we need
4518 this so it can be shared */
4519 CData_GetContainer(obj);
4520 /* But we need a dictionary! */
4521 if (obj->b_objects == Py_None) {
4522 Py_DECREF(Py_None);
4523 obj->b_objects = PyDict_New();
4524 if (obj->b_objects == NULL)
4525 goto failed;
4527 result->b_objects = obj->b_objects;
4528 if (result->b_objects) {
4529 PyObject *index;
4530 int rc;
4531 Py_INCREF(obj->b_objects);
4532 index = PyLong_FromVoidPtr((void *)src);
4533 if (index == NULL)
4534 goto failed;
4535 rc = PyDict_SetItem(result->b_objects, index, src);
4536 Py_DECREF(index);
4537 if (rc == -1)
4538 goto failed;
4541 /* Should we assert that result is a pointer type? */
4542 memcpy(result->b_ptr, &ptr, sizeof(void *));
4543 return (PyObject *)result;
4545 failed:
4546 Py_DECREF(result);
4547 return NULL;
4550 #ifdef CTYPES_UNICODE
4551 static PyObject *
4552 wstring_at(const wchar_t *ptr, int size)
4554 if (size == 0)
4555 size = wcslen(ptr);
4556 return PyUnicode_FromWideChar(ptr, size);
4558 #endif
4560 PyMODINIT_FUNC
4561 init_ctypes(void)
4563 PyObject *m;
4565 /* Note:
4566 ob_type is the metatype (the 'type'), defaults to PyType_Type,
4567 tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
4569 #ifdef WITH_THREAD
4570 PyEval_InitThreads();
4571 #endif
4572 m = Py_InitModule3("_ctypes", module_methods, module_docs);
4573 if (!m)
4574 return;
4576 if (PyType_Ready(&PyCArg_Type) < 0)
4577 return;
4579 /* StgDict is derived from PyDict_Type */
4580 StgDict_Type.tp_base = &PyDict_Type;
4581 if (PyType_Ready(&StgDict_Type) < 0)
4582 return;
4584 /*************************************************
4586 * Metaclasses
4589 StructType_Type.tp_base = &PyType_Type;
4590 if (PyType_Ready(&StructType_Type) < 0)
4591 return;
4593 UnionType_Type.tp_base = &PyType_Type;
4594 if (PyType_Ready(&UnionType_Type) < 0)
4595 return;
4597 PointerType_Type.tp_base = &PyType_Type;
4598 if (PyType_Ready(&PointerType_Type) < 0)
4599 return;
4601 ArrayType_Type.tp_base = &PyType_Type;
4602 if (PyType_Ready(&ArrayType_Type) < 0)
4603 return;
4605 SimpleType_Type.tp_base = &PyType_Type;
4606 if (PyType_Ready(&SimpleType_Type) < 0)
4607 return;
4609 CFuncPtrType_Type.tp_base = &PyType_Type;
4610 if (PyType_Ready(&CFuncPtrType_Type) < 0)
4611 return;
4613 /*************************************************
4615 * Classes using a custom metaclass
4618 if (PyType_Ready(&CData_Type) < 0)
4619 return;
4621 Struct_Type.ob_type = &StructType_Type;
4622 Struct_Type.tp_base = &CData_Type;
4623 if (PyType_Ready(&Struct_Type) < 0)
4624 return;
4625 PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
4627 Union_Type.ob_type = &UnionType_Type;
4628 Union_Type.tp_base = &CData_Type;
4629 if (PyType_Ready(&Union_Type) < 0)
4630 return;
4631 PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
4633 Pointer_Type.ob_type = &PointerType_Type;
4634 Pointer_Type.tp_base = &CData_Type;
4635 if (PyType_Ready(&Pointer_Type) < 0)
4636 return;
4637 PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
4639 Array_Type.ob_type = &ArrayType_Type;
4640 Array_Type.tp_base = &CData_Type;
4641 if (PyType_Ready(&Array_Type) < 0)
4642 return;
4643 PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
4645 Simple_Type.ob_type = &SimpleType_Type;
4646 Simple_Type.tp_base = &CData_Type;
4647 if (PyType_Ready(&Simple_Type) < 0)
4648 return;
4649 PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
4651 CFuncPtr_Type.ob_type = &CFuncPtrType_Type;
4652 CFuncPtr_Type.tp_base = &CData_Type;
4653 if (PyType_Ready(&CFuncPtr_Type) < 0)
4654 return;
4655 PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
4657 /*************************************************
4659 * Simple classes
4662 /* CField_Type is derived from PyBaseObject_Type */
4663 if (PyType_Ready(&CField_Type) < 0)
4664 return;
4666 /*************************************************
4668 * Other stuff
4671 #ifdef MS_WIN32
4672 if (create_comerror() < 0)
4673 return;
4674 PyModule_AddObject(m, "COMError", ComError);
4676 PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyInt_FromLong(FUNCFLAG_HRESULT));
4677 PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
4678 #endif
4679 PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
4680 PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
4681 PyModule_AddStringConstant(m, "__version__", "1.0.0");
4683 PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
4684 PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
4685 PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
4686 PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
4687 #ifdef CTYPES_UNICODE
4688 PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
4689 #endif
4691 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
4692 #ifndef RTLD_LOCAL
4693 #define RTLD_LOCAL 0
4694 #endif
4696 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
4697 RTLD_LOCAL.
4699 #ifndef RTLD_GLOBAL
4700 #define RTLD_GLOBAL RTLD_LOCAL
4701 #endif
4703 PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
4704 PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
4706 PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
4707 if (PyExc_ArgError) {
4708 Py_INCREF(PyExc_ArgError);
4709 PyModule_AddObject(m, "ArgumentError", PyExc_ArgError);
4711 /*************************************************
4713 * Others...
4715 init_callbacks_in_module(m);
4718 /*****************************************************************
4719 * replacements for broken Python api functions (in Python 2.3).
4720 * See #1047269 Buffer overwrite in PyUnicode_AsWideChar
4723 #ifdef HAVE_WCHAR_H
4725 PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w,
4726 Py_ssize_t size)
4728 PyUnicodeObject *unicode;
4730 if (w == NULL) {
4731 PyErr_BadInternalCall();
4732 return NULL;
4735 unicode = (PyUnicodeObject *)PyUnicode_FromUnicode(NULL, size);
4736 if (!unicode)
4737 return NULL;
4739 /* Copy the wchar_t data into the new object */
4740 #ifdef HAVE_USABLE_WCHAR_T
4741 memcpy(unicode->str, w, size * sizeof(wchar_t));
4742 #else
4744 register Py_UNICODE *u;
4745 register int i;
4746 u = PyUnicode_AS_UNICODE(unicode);
4747 /* In Python, the following line has a one-off error */
4748 for (i = size; i > 0; i--)
4749 *u++ = *w++;
4751 #endif
4753 return (PyObject *)unicode;
4756 int My_PyUnicode_AsWideChar(PyUnicodeObject *unicode,
4757 register wchar_t *w,
4758 Py_ssize_t size)
4760 if (unicode == NULL) {
4761 PyErr_BadInternalCall();
4762 return -1;
4764 if (size > PyUnicode_GET_SIZE(unicode))
4765 size = PyUnicode_GET_SIZE(unicode);
4766 #ifdef HAVE_USABLE_WCHAR_T
4767 memcpy(w, unicode->str, size * sizeof(wchar_t));
4768 #else
4770 register Py_UNICODE *u;
4771 register int i;
4772 u = PyUnicode_AS_UNICODE(unicode);
4773 /* In Python, the following line has a one-off error */
4774 for (i = size; i > 0; i--)
4775 *w++ = *u++;
4777 #endif
4779 return size;
4782 #endif
4785 Local Variables:
4786 compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
4787 End: