[pybank] Improve handling of structs as return values



commit f80b39aa1b969c7e7d4a8088e7fb55c755bace7d
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date:   Tue May 12 10:26:56 2009 +0200

    Improve handling of structs as return values
---
 bank/bank-argument.c |   25 +++++++++++++++++++++----
 bank/bank-info.c     |   21 +++++++++++++++------
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/bank/bank-argument.c b/bank/bank-argument.c
index 571f583..c2870d4 100644
--- a/bank/bank-argument.c
+++ b/bank/bank-argument.c
@@ -133,13 +133,30 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
             const gchar *type_name = g_base_info_get_name(interface_info);
             PyObject *module = PyImport_ImportModule(module_name);
             PyObject *tp = PyObject_GetAttrString(module, type_name);
-            gsize size = g_struct_info_get_size ((GIStructInfo*)type_info);
-            PyObject *buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
-            PyObject *args = Py_BuildValue("(O)", buffer);
+            gsize size;
+            PyObject *buffer;
+            PyObject **dict;
 
-            obj = PyObject_Call(tp, args, NULL);
+            if (tp == NULL) {
+                char buf[256];
+                snprintf(buf, sizeof(buf), "Type %s.%s not defined", module_name, type_name);
+                PyErr_SetString(PyExc_TypeError, buf);
+                return NULL;
+            }
+
+            obj = PyObject_New(PyObject, (PyTypeObject *) tp);
             if (obj == NULL)
                 return NULL;
+
+            // FIXME: Any better way to initialize the dict pointer?
+            dict = (PyObject **) ((char *)obj + ((PyTypeObject *) tp)->tp_dictoffset);
+            *dict = NULL;
+
+            size = g_struct_info_get_size ((GIStructInfo*)type_info);
+            buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
+
+            PyObject_SetAttrString(obj, "__buffer__", buffer);
+
             Py_INCREF(obj);
             return obj;
         } else if (interface_type == GI_INFO_TYPE_ENUM) {
diff --git a/bank/bank-info.c b/bank/bank-info.c
index 9f220f3..389ace2 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -409,9 +409,10 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
         if (py_arg == Py_None) {
             in_args[0].v_pointer = NULL;
         } else if (type == GI_INFO_TYPE_STRUCT || type == GI_INFO_TYPE_BOXED) {
-            PyObject *buffer = PyObject_GetAttrString((PyObject *)py_arg,
-                                                      "__buffer__");
-            in_args[0].v_pointer = PyString_AsString(buffer);
+            PyObject *pybuffer = PyObject_GetAttrString((PyObject *)py_arg,
+                                                        "__buffer__");
+            PyBufferProcs *buffer_procs = pybuffer->ob_type->tp_as_buffer;
+            (*buffer_procs->bf_getreadbuffer)(pybuffer, 0, &in_args[0].v_pointer);
         } else { /* by fallback is always object */
             in_args[0].v_pointer = pygobject_get(py_arg);
         }
@@ -542,9 +543,13 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
         n_return_values += 1;
 
     return_values = g_newa(PyObject*, n_return_values);
-    if (n_return_values > 0) {
+    if (!is_constructor && n_return_values > 0) {
         if (return_tag != GI_TYPE_TAG_VOID) {
-            return_values[next_rval] = pyg_argument_to_pyobject(&return_arg, return_info);
+            PyObject *obj = pyg_argument_to_pyobject(&return_arg, return_info);
+            if (obj == NULL) {
+                return NULL;
+            }
+            return_values[next_rval] = obj;
 
             ++next_rval;
         }
@@ -577,7 +582,11 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
             g_assert(next_rval < n_return_values);
             g_assert(out_args_pos < expected_out_argc);
 
-            return_values[next_rval] = pyg_argument_to_pyobject(&out_args[out_args_pos], arg_type_info);
+            PyObject *obj = pyg_argument_to_pyobject(&out_args[out_args_pos], arg_type_info);
+            if (obj == NULL) {
+                return NULL;
+            }
+            return_values[next_rval] = obj;
 
             if (direction == GI_DIRECTION_INOUT)
                 ++in_args_pos;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]