diff -up -ru pygobject-3.0.3.orig/gi/_gobject/ffi-marshaller.c pygobject-3.0.3/gi/_gobject/ffi-marshaller.c
--- pygobject-3.0.3.orig/gi/_gobject/ffi-marshaller.c	2011-11-02 14:13:28.000000000 +0100
+++ pygobject-3.0.3/gi/_gobject/ffi-marshaller.c	2012-01-27 17:29:54.000000000 +0100
@@ -82,51 +82,128 @@ g_value_to_ffi_type (const GValue *gvalu
   return rettype;
 }
 
+/* Extract the correct bits from an ffi_arg return value into
+ * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
+ *
+ * Also see the ffi_call man page - the storage requirements for return
+ * values are "special".
+ */
+union FFIReturnValue {
+    ffi_arg  rv_ffi_arg;
+    ffi_sarg rv_ffi_sarg;
+    guint64  rv_u64;
+    gint64   rv_s64;
+    float    rv_float;
+    double   rv_double;
+};
+
+static ffi_type *
+g_value_to_ffi_return_type (const GValue *gvalue,
+			    const union FFIReturnValue *ffi_value,
+			    gpointer *value)
+{
+  ffi_type *rettype = NULL;
+  GType type = g_type_fundamental (G_VALUE_TYPE (gvalue));
+  g_assert (type != G_TYPE_INVALID);
+
+  *value = (gpointer)&(ffi_value->rv_ffi_arg);
+
+  switch (type) {
+  case G_TYPE_CHAR:
+    rettype = &ffi_type_sint8;
+    break;
+  case G_TYPE_UCHAR:
+    rettype = &ffi_type_uint8;
+    break;
+  case G_TYPE_BOOLEAN:
+  case G_TYPE_INT:
+    rettype = &ffi_type_sint;
+    break;
+  case G_TYPE_UINT:
+    rettype = &ffi_type_uint;
+    break;
+  case G_TYPE_STRING:
+  case G_TYPE_OBJECT:
+  case G_TYPE_BOXED:
+  case G_TYPE_POINTER:
+    rettype = &ffi_type_pointer;
+    break;
+  case G_TYPE_FLOAT:
+    rettype = &ffi_type_float;
+    *value = (gpointer)&(ffi_value->rv_float);
+    break;
+  case G_TYPE_DOUBLE:
+    rettype = &ffi_type_double;
+    *value = (gpointer)&(ffi_value->rv_double);
+    break;
+  case G_TYPE_LONG:
+    rettype = &ffi_type_slong;
+    break;
+  case G_TYPE_ULONG:
+    rettype = &ffi_type_ulong;
+    break;
+  case G_TYPE_INT64:
+    rettype = &ffi_type_sint64;
+    *value = (gpointer)&(ffi_value->rv_s64);
+    break;
+  case G_TYPE_UINT64:
+    rettype = &ffi_type_uint64;
+    *value = (gpointer)&(ffi_value->rv_u64);
+    break;
+  default:
+    rettype = &ffi_type_pointer;
+    *value = NULL;
+    g_warning ("Unsupported fundamental type: %s", g_type_name (type));
+    break;
+  }
+  return rettype;
+}
+
 static void
-g_value_from_ffi_type (GValue *gvalue, gpointer *value)
+g_value_from_ffi_value (GValue *gvalue, const union FFIReturnValue *value)
 {
   switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) {
   case G_TYPE_INT:
-      g_value_set_int (gvalue, *(gint*)value);
+      g_value_set_int (gvalue, (gint)value->rv_ffi_sarg);
       break;
   case G_TYPE_FLOAT:
-      g_value_set_float (gvalue, *(gfloat*)value);
+      g_value_set_float (gvalue, (gfloat)value->rv_float);
       break;
   case G_TYPE_DOUBLE:
-      g_value_set_double (gvalue, *(gdouble*)value);
+      g_value_set_double (gvalue, (gdouble)value->rv_double);
       break;
   case G_TYPE_BOOLEAN:
-      g_value_set_boolean (gvalue, *(gboolean*)value);
+      g_value_set_boolean (gvalue, (gboolean)value->rv_ffi_arg);
       break;
   case G_TYPE_STRING:
-      g_value_set_string (gvalue, *(gchar**)value);
+      g_value_set_string (gvalue, (gchar*)value->rv_ffi_arg);
       break;
   case G_TYPE_CHAR:
-      g_value_set_char (gvalue, *(gchar*)value);
+      g_value_set_char (gvalue, (gchar)value->rv_ffi_sarg);
       break;
   case G_TYPE_UCHAR:
-      g_value_set_uchar (gvalue, *(guchar*)value);
+      g_value_set_uchar (gvalue, (guchar)value->rv_ffi_arg);
       break;
   case G_TYPE_UINT:
-      g_value_set_uint (gvalue, *(guint*)value);
+      g_value_set_uint (gvalue, (guint)value->rv_ffi_arg);
       break;
   case G_TYPE_POINTER:
-      g_value_set_pointer (gvalue, *(gpointer*)value);
+      g_value_set_pointer (gvalue, (gpointer)value->rv_ffi_arg);
       break;
   case G_TYPE_LONG:
-      g_value_set_long (gvalue, *(glong*)value);
+      g_value_set_long (gvalue, (glong)value->rv_ffi_sarg);
       break;
   case G_TYPE_ULONG:
-      g_value_set_ulong (gvalue, *(gulong*)value);
+      g_value_set_ulong (gvalue, (gulong)value->rv_ffi_arg);
       break;
   case G_TYPE_INT64:
-      g_value_set_int64 (gvalue, *(gint64*)value);
+      g_value_set_int64 (gvalue, (gint64)value->rv_s64);
       break;
   case G_TYPE_UINT64:
-      g_value_set_uint64 (gvalue, *(guint64*)value);
+      g_value_set_uint64 (gvalue, (guint64)value->rv_u64);
       break;
   case G_TYPE_BOXED:
-      g_value_set_boxed (gvalue, *(gpointer*)value);
+      g_value_set_boxed (gvalue, (gpointer)value->rv_ffi_sarg);
       break;
   default:
     g_warning ("Unsupported fundamental type: %s",
@@ -143,6 +220,7 @@ g_cclosure_marshal_generic_ffi (GClosure
 				gpointer invocation_hint,
 				gpointer marshal_data)
 {
+  union FFIReturnValue return_ffi_value;
   ffi_type *rtype;
   void *rvalue;
   int n_args;
@@ -154,15 +232,15 @@ g_cclosure_marshal_generic_ffi (GClosure
 
   if (return_gvalue && G_VALUE_TYPE (return_gvalue)) 
     {
-      rtype = g_value_to_ffi_type (return_gvalue, &rvalue);
+      rtype = g_value_to_ffi_return_type (return_gvalue, &return_ffi_value,
+					  &rvalue);
     }
   else 
     {
       rtype = &ffi_type_void;
+      rvalue = &return_ffi_value.rv_ffi_arg;
     }
 
-  rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg)));
-  
   n_args = n_param_values + 1;
   atypes = g_alloca (sizeof (ffi_type *) * n_args);
   args =  g_alloca (sizeof (gpointer) * n_args);
@@ -190,5 +268,5 @@ g_cclosure_marshal_generic_ffi (GClosure
   ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args);
 
   if (return_gvalue && G_VALUE_TYPE (return_gvalue))
-    g_value_from_ffi_type (return_gvalue, rvalue);
+    g_value_from_ffi_value (return_gvalue, &return_ffi_value);
 }
diff -up -ru pygobject-3.0.3.orig/gi/pygi-marshal-from-py.c pygobject-3.0.3/gi/pygi-marshal-from-py.c
--- pygobject-3.0.3.orig/gi/pygi-marshal-from-py.c	2011-11-03 10:33:41.000000000 +0100
+++ pygobject-3.0.3/gi/pygi-marshal-from-py.c	2012-01-27 18:32:32.000000000 +0100
@@ -148,7 +148,7 @@ _pygi_marshal_from_py_int8 (PyGIInvokeSt
         return FALSE;
     }
 
-    arg->v_long = long_;
+    arg->v_int8 = long_;
 
     return TRUE;
 }
@@ -197,7 +197,7 @@ _pygi_marshal_from_py_uint8 (PyGIInvokeS
         return FALSE;
     }
 
-    arg->v_long = long_;
+    arg->v_uint8 = long_;
 
     return TRUE;
 }
@@ -236,7 +236,7 @@ _pygi_marshal_from_py_int16 (PyGIInvokeS
         return FALSE;
     }
 
-    arg->v_long = long_;
+    arg->v_int16 = long_;
 
     return TRUE;
 }
@@ -275,7 +275,7 @@ _pygi_marshal_from_py_uint16 (PyGIInvoke
         return FALSE;
     }
 
-    arg->v_long = long_;
+    arg->v_uint16 = long_;
 
     return TRUE;
 }
@@ -314,7 +314,7 @@ _pygi_marshal_from_py_int32 (PyGIInvokeS
         return FALSE;
     }
 
-    arg->v_long = long_;
+    arg->v_int32 = long_;
 
     return TRUE;
 }
@@ -359,7 +359,7 @@ _pygi_marshal_from_py_uint32 (PyGIInvoke
         return FALSE;
     }
 
-    arg->v_uint64 = long_;
+    arg->v_uint32 = long_;
 
     return TRUE;
 }
