diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+### 0.20.6
+
++ Use g_object_new_with_properties instead of g_object_newv in
+GLib versions 2.54 or later, to avoid a deprecation warning.
+
 ### 0.20.5
 
 + Run object finalizers in the main loop. The reason is that for
diff --git a/Data/GI/Base/GObject.hsc b/Data/GI/Base/GObject.hsc
--- a/Data/GI/Base/GObject.hsc
+++ b/Data/GI/Base/GObject.hsc
@@ -20,8 +20,8 @@
 
 #include <glib-object.h>
 
-foreign import ccall "dbg_g_object_newv" g_object_newv ::
-    GType -> CUInt -> Ptr a -> IO (Ptr b)
+foreign import ccall "dbg_g_object_new" g_object_new ::
+    GType -> CUInt -> Ptr CString -> Ptr a -> IO (Ptr b)
 
 -- | Construct a GObject given the constructor and a list of settable
 -- attributes.
@@ -46,18 +46,19 @@
                       => (ManagedPtr o -> o) -> [GValueConstruct o] -> m o
 doConstructGObject constructor props = liftIO $ do
   let nprops = length props
-  params <- mallocBytes (nprops*gparameterSize)
-  fill params props
+  names <- mallocBytes (nprops * sizeOf nullPtr)
+  values <- mallocBytes (nprops * gvalueSize)
+  fill names values props
   gtype <- gobjectType (undefined :: o)
-  result <- g_object_newv gtype (fromIntegral nprops) params
-  freeStrings nprops params
-  free params
+  result <- g_object_new gtype (fromIntegral nprops) names values
+  freeStrings nprops names
+  free values
   -- Make sure that the GValues defining the GProperties are still
   -- alive at this point (so, in particular, they are still alive when
-  -- g_object_newv is called). Without this the GHC garbage collector
-  -- may free the GValues before g_object_newv is called, which will
+  -- g_object_new is called). Without this the GHC garbage collector
+  -- may free the GValues before g_object_new is called, which will
   -- unref the referred to objects, which may drop the last reference
-  -- to the contained objects. g_object_newv then tries to access the
+  -- to the contained objects. g_object_new then tries to access the
   -- (now invalid) contents of the GValue, and mayhem ensues.
   mapM_ (touchManagedPtr . deconstructGValue) props
   wrapObject constructor (result :: Ptr o)
@@ -67,27 +68,25 @@
     deconstructGValue (GValueConstruct _ v) = v
 
     gvalueSize = #size GValue
-    gparameterSize = #size GParameter
 
-    -- Fill the given memory address with the contents of the array of
-    -- GParameters.
-    fill :: Ptr () -> [GValueConstruct o] -> IO ()
-    fill _ [] = return ()
-    fill dataPtr ((GValueConstruct str gvalue):xs) =
+    -- Fill in the memory associated with the parameters.
+    fill :: Ptr CString -> Ptr GValue -> [GValueConstruct o] -> IO ()
+    fill _ _ [] = return ()
+    fill namePtr dataPtr ((GValueConstruct str gvalue):xs) =
         do cstr <- newCString str
-           poke (castPtr dataPtr) cstr
+           poke namePtr cstr
            withManagedPtr gvalue $ \gvalueptr ->
-               copyBytes (dataPtr `plusPtr` sizeOf nullPtr) gvalueptr gvalueSize
-           fill (dataPtr `plusPtr` gparameterSize) xs
+                                     copyBytes dataPtr gvalueptr gvalueSize
+           fill (namePtr `plusPtr` sizeOf nullPtr)
+                (dataPtr `plusPtr` gvalueSize) xs
 
     -- Free the strings in the GParameter array (the GValues will be
     -- freed separately).
-    freeStrings :: Int -> Ptr () -> IO ()
+    freeStrings :: Int -> Ptr CString -> IO ()
     freeStrings 0 _ = return ()
-    freeStrings n dataPtr =
-        do cstr <- peek (castPtr dataPtr) :: IO CString
-           free cstr
-           freeStrings (n-1) (dataPtr `plusPtr` gparameterSize)
+    freeStrings n namePtr =
+        do peek namePtr >>= free
+           freeStrings (n-1) (namePtr `plusPtr` sizeOf nullPtr)
 
 -- | Construct the given `GObject`, given a set of actions
 -- constructing desired `GValue`s to set at construction time.
diff --git a/c/hsgclosure.c b/c/hsgclosure.c
--- a/c/hsgclosure.c
+++ b/c/hsgclosure.c
@@ -4,6 +4,7 @@
 #include <Rts.h>
 
 #include <stdlib.h>
+#include <string.h>
 
 #include <glib-object.h>
 #include <glib.h>
@@ -128,8 +129,9 @@
 /**
  * dbg_g_object_new:
  * @gtype: #GType for the object to construct.
- * @n_params: Number of parameters for g_object_newv().
- * @params: (array length=n_params) Parameters for g_object_newv().
+ * @n_props: Number of parameters for g_object_new_with_properties().
+ * @names: Names of the properties to be set.
+ * @values: Parameters for g_object_new_with_properties().
  *
  * Allocate a #GObject of #GType @gtype, with the given @params. The
  * returned object is never floating, and we always own a reference to
@@ -139,7 +141,8 @@
  *
  * Returns: A new #GObject.
  */
-gpointer dbg_g_object_newv (GType gtype, guint n_params, GParameter *params)
+gpointer dbg_g_object_new (GType gtype, guint n_props,
+                           const char *names[], const GValue values[])
 {
   gpointer result;
 
@@ -150,7 +153,20 @@
             g_type_name(gtype), self);
   }
 
-  result = g_object_newv (gtype, n_params, params);
+#if GLIB_CHECK_VERSION(2,54,0)
+  result = g_object_new_with_properties (gtype, n_props, names, values);
+#else
+  { GParameter params[n_props];
+    int i;
+
+    for (i=0; i<n_props; i++) {
+      memcpy (&params[i].value, &values[i], sizeof(GValue));
+      params[i].name = names[i];
+    }
+
+    result = g_object_newv (gtype, n_props, params);
+  }
+#endif
 
   /*
     Initially unowned GObjects can be either floating or not after
diff --git a/haskell-gi-base.cabal b/haskell-gi-base.cabal
--- a/haskell-gi-base.cabal
+++ b/haskell-gi-base.cabal
@@ -1,5 +1,5 @@
 name:                haskell-gi-base
-version:             0.20.5
+version:             0.20.6
 synopsis:            Foundation for libraries generated by haskell-gi
 description:         Foundation for libraries generated by haskell-gi
 homepage:            https://github.com/haskell-gi/haskell-gi-base
