mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
Merged revisions 60767,60768 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r60767 | thomas.heller | 2008-02-13 21:21:53 +0100 (Mi, 13 Feb 2008) | 1 line Add pickle support to ctypes types. ........ r60768 | thomas.heller | 2008-02-13 21:36:51 +0100 (Mi, 13 Feb 2008) | 1 line Make the test somewhat clearer (I hope). ........
This commit is contained in:
parent
2bc6b5eb36
commit
13394e907d
6 changed files with 174 additions and 1 deletions
|
@ -123,6 +123,9 @@ bytes(cdata)
|
|||
PyObject *PyExc_ArgError;
|
||||
static PyTypeObject Simple_Type;
|
||||
|
||||
/* a callable object used for unpickling */
|
||||
static PyObject *_unpickle;
|
||||
|
||||
char *conversion_mode_encoding = NULL;
|
||||
char *conversion_mode_errors = NULL;
|
||||
|
||||
|
@ -710,6 +713,7 @@ PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
stgdict->length = 1;
|
||||
stgdict->ffi_type_pointer = ffi_type_pointer;
|
||||
stgdict->paramfunc = PointerType_paramfunc;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
|
||||
proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
|
||||
if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
|
||||
|
@ -1139,6 +1143,9 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
|
||||
itemalign = itemdict->align;
|
||||
|
||||
if (itemdict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
|
||||
stgdict->flags |= TYPEFLAG_HASPOINTER;
|
||||
|
||||
stgdict->size = itemsize * length;
|
||||
stgdict->align = itemalign;
|
||||
stgdict->length = length;
|
||||
|
@ -1706,12 +1713,21 @@ SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
switch (*proto_str) {
|
||||
case 'z': /* c_char_p */
|
||||
ml = &c_char_p_method;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
break;
|
||||
case 'Z': /* c_wchar_p */
|
||||
ml = &c_wchar_p_method;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
break;
|
||||
case 'P': /* c_void_p */
|
||||
ml = &c_void_p_method;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
break;
|
||||
case 'u':
|
||||
case 'X':
|
||||
case 'O':
|
||||
ml = NULL;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
break;
|
||||
default:
|
||||
ml = NULL;
|
||||
|
@ -1928,7 +1944,7 @@ make_funcptrtype_dict(StgDictObject *stgdict)
|
|||
"class must define _flags_ which must be an integer");
|
||||
return -1;
|
||||
}
|
||||
stgdict->flags = PyLong_AS_LONG(ob);
|
||||
stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER;
|
||||
|
||||
/* _argtypes_ is optional... */
|
||||
ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_");
|
||||
|
@ -2003,6 +2019,7 @@ CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
|
||||
stgdict->paramfunc = CFuncPtrType_paramfunc;
|
||||
stgdict->flags |= TYPEFLAG_ISPOINTER;
|
||||
|
||||
/* create the new instance (which is a class,
|
||||
since we are a metatype!) */
|
||||
|
@ -2235,6 +2252,45 @@ CData_nohash(PyObject *self)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
CData_reduce(PyObject *_self, PyObject *args)
|
||||
{
|
||||
CDataObject *self = (CDataObject *)_self;
|
||||
|
||||
if (PyObject_stgdict(_self)->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"ctypes objects containing pointers cannot be pickled");
|
||||
return NULL;
|
||||
}
|
||||
return Py_BuildValue("O(O(NN))",
|
||||
_unpickle,
|
||||
Py_TYPE(_self),
|
||||
PyObject_GetAttrString(_self, "__dict__"),
|
||||
PyString_FromStringAndSize(self->b_ptr, self->b_size));
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
CData_setstate(PyObject *_self, PyObject *args)
|
||||
{
|
||||
void *data;
|
||||
int len;
|
||||
int res;
|
||||
PyObject *dict, *mydict;
|
||||
CDataObject *self = (CDataObject *)_self;
|
||||
if (!PyArg_ParseTuple(args, "Os#", &dict, &data, &len))
|
||||
return NULL;
|
||||
if (len > self->b_size)
|
||||
len = self->b_size;
|
||||
memmove(self->b_ptr, data, len);
|
||||
mydict = PyObject_GetAttrString(_self, "__dict__");
|
||||
res = PyDict_Update(mydict, dict);
|
||||
Py_DECREF(mydict);
|
||||
if (res == -1)
|
||||
return NULL;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
/*
|
||||
* default __ctypes_from_outparam__ method returns self.
|
||||
*/
|
||||
|
@ -2247,6 +2303,8 @@ CData_from_outparam(PyObject *self, PyObject *args)
|
|||
|
||||
static PyMethodDef CData_methods[] = {
|
||||
{ "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, },
|
||||
{ "__reduce__", CData_reduce, METH_NOARGS, },
|
||||
{ "__setstate__", CData_setstate, METH_VARARGS, },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -4934,6 +4992,10 @@ init_ctypes(void)
|
|||
if (!m)
|
||||
return;
|
||||
|
||||
_unpickle = PyObject_GetAttrString(m, "_unpickle");
|
||||
if (_unpickle == NULL)
|
||||
return;
|
||||
|
||||
if (PyType_Ready(&PyCArg_Type) < 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1543,7 +1543,30 @@ resize(PyObject *self, PyObject *args)
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
unpickle(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *typ;
|
||||
PyObject *state;
|
||||
PyObject *result;
|
||||
PyObject *tmp;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO", &typ, &state))
|
||||
return NULL;
|
||||
result = PyObject_CallMethod(typ, "__new__", "O", typ);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
tmp = PyObject_CallMethod(result, "__setstate__", "O", state);
|
||||
if (tmp == NULL) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
PyMethodDef module_methods[] = {
|
||||
{"_unpickle", unpickle, METH_VARARGS },
|
||||
{"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
|
||||
#ifdef CTYPES_UNICODE
|
||||
{"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
|
||||
|
|
|
@ -269,6 +269,9 @@ PyObject *_CallProc(PPROC pProc,
|
|||
#define FUNCFLAG_HRESULT 0x2
|
||||
#define FUNCFLAG_PYTHONAPI 0x4
|
||||
|
||||
#define TYPEFLAG_ISPOINTER 0x100
|
||||
#define TYPEFLAG_HASPOINTER 0x200
|
||||
|
||||
#define DICTFLAG_FINAL 0x1000
|
||||
|
||||
struct tagPyCArgObject {
|
||||
|
|
|
@ -402,6 +402,8 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
|
|||
return -1;
|
||||
}
|
||||
stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer;
|
||||
if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
|
||||
stgdict->flags |= TYPEFLAG_HASPOINTER;
|
||||
dict->flags |= DICTFLAG_FINAL; /* mark field type final */
|
||||
if (PyTuple_Size(pair) == 3) { /* bits specified */
|
||||
switch(dict->ffi_type_pointer.type) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue