diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+### 0.24.3
+
++ Provide type init functions for GParamSpec types. This solves a puzzling linker error saying that the "intern" symbol could not be resolved, see [issue 297](https://github.com/haskell-gi/haskell-gi/issues/297) and [issue 298](https://github.com/haskell-gi/haskell-gi/issues/298).
+
 ### 0.24.2
 
 + Support for allocating GArrays of known size structs in caller-allocates arguments.
diff --git a/haskell-gi.cabal b/haskell-gi.cabal
--- a/haskell-gi.cabal
+++ b/haskell-gi.cabal
@@ -1,5 +1,5 @@
 name:                haskell-gi
-version:             0.24.2
+version:             0.24.3
 synopsis:            Generate Haskell bindings for GObject Introspection capable libraries
 description:         Generate Haskell bindings for GObject Introspection capable libraries. This includes most notably
                      Gtk+, but many other libraries in the GObject ecosystem provide introspection data too.
@@ -33,7 +33,7 @@
   default-language:    Haskell2010
   pkgconfig-depends:   gobject-introspection-1.0 >= 1.32, gobject-2.0 >= 2.32
   build-depends:       base >= 4.9 && < 5,
-                       haskell-gi-base >= 0.24.1 && <0.25,
+                       haskell-gi-base >= 0.24.2 && <0.25,
                        Cabal >= 1.24,
                        attoparsec >= 0.13,
                        containers,
diff --git a/lib/Data/GI/CodeGen/CodeGen.hs b/lib/Data/GI/CodeGen/CodeGen.hs
--- a/lib/Data/GI/CodeGen/CodeGen.hs
+++ b/lib/Data/GI/CodeGen/CodeGen.hs
@@ -245,14 +245,16 @@
 
 -- Type casting with type checking
 genCasts :: Name -> Text -> [Name] -> CodeGen ()
-genCasts n cn_ parents = do
+genCasts n ti parents = do
   isGO <- isGObject (TInterface n)
   let name' = upperName n
-      get_type_fn = "c_" <> cn_
 
-  group $ do
-    line $ "foreign import ccall \"" <> cn_ <> "\""
-    indent $ line $ get_type_fn <> " :: IO B.Types.GType"
+  get_type_fn <- do
+    let cn_ = "c_" <> ti
+    group $ do
+      line $ "foreign import ccall \"" <> ti <> "\""
+      indent $ line $ cn_ <> " :: IO B.Types.GType"
+    return cn_
 
   group $ do
     bline $ "instance B.Types.TypedObject " <> name' <> " where"
@@ -467,14 +469,7 @@
 genModule' apis = do
   mapM_ (uncurry genAPIModule)
     -- We provide these ourselves
-    $ filter ((`notElem` [ Name "GLib" "Array"
-                         , Name "GLib" "Error"
-                         , Name "GLib" "HashTable"
-                         , Name "GLib" "List"
-                         , Name "GLib" "SList"
-                         , Name "GLib" "Variant"
-                         , Name "GObject" "Value"
-                         , Name "GObject" "Closure"]) . fst)
+    $ filter (not . handWritten)
     -- Some callback types are defined inside structs
     $ map fixAPIStructs
     -- Some APIs contain duplicated fields by mistake, drop
@@ -486,6 +481,20 @@
   -- Make sure we generate a "Callbacks" module, since it is imported
   -- by other modules. It is fine if it ends up empty.
   submodule "Callbacks" (return ())
+  where
+    -- Whether we provide hand-written bindings for the given API,
+    -- replacing the ones that would be autogenerated from the
+    -- introspection data.
+    handWritten :: (Name, API) -> Bool
+    handWritten (Name "GLib" "Array", _) = True
+    handWritten (Name "GLib" "Error", _) = True
+    handWritten (Name "GLib" "HashTable", _) = True
+    handWritten (Name "GLib" "List", _) = True
+    handWritten (Name "GLib" "SList", _) = True
+    handWritten (Name "GLib" "Variant", _) = True
+    handWritten (Name "GObject" "Value", _) = True
+    handWritten (Name "GObject" "Closure", _) = True
+    handWritten _ = False
 
 genModule :: M.Map Name API -> CodeGen ()
 genModule apis = do
diff --git a/lib/Data/GI/GIR/Object.hs b/lib/Data/GI/GIR/Object.hs
--- a/lib/Data/GI/GIR/Object.hs
+++ b/lib/Data/GI/GIR/Object.hs
@@ -38,7 +38,10 @@
   parent <- optionalAttr "parent" Nothing (fmap Just . qualifyName)
   interfaces <- parseChildrenWithLocalName "implements" parseName
   props <- parseChildrenWithLocalName "property" parseProperty
-  typeInit <- getAttrWithNamespace GLibGIRNS "get-type"
+  typeInitFn <- getAttrWithNamespace GLibGIRNS "get-type"
+  typeInit <- case typeInitFn of
+                "intern" -> resolveInternalType name
+                fn -> return fn
   typeName <- getAttrWithNamespace GLibGIRNS "type-name"
   signals <- parseChildrenWithNSName GLibGIRNS "signal" parseSignal
   refFunc <- queryAttrWithNamespace GLibGIRNS "ref-func"
@@ -61,3 +64,39 @@
           , objSignals = signals
           })
 
+-- | Some basic types do not list a type init function, and instead
+-- mention "intern". Provide the explicit numerical value of the GType
+-- in these cases.
+resolveInternalType :: Name -> Parser Text
+resolveInternalType (Name "GObject" p@"ParamSpec") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecBoolean") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecBoxed") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecChar") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecDouble") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecEnum") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecFlags") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecFloat") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecGType") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecInt") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecInt64") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecLong") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecObject") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecOverride") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecParam") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecPointer") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecString") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecUChar") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecUInt") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecUInt64") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecULong") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecUnichar") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecVariant") = pspec_type_init p
+resolveInternalType (Name "GObject" p@"ParamSpecValueArray") = pspec_type_init p
+resolveInternalType (Name ns n) =
+  parseError $ "Unknown internal type: " <> ns <> "." <> n <> "\n"
+                <> "This is a bug, please report at https://github.com/haskell-gi/haskell-gi/issues"
+
+-- | The name of the function we provide for querying ParamSpec types
+-- at runtime.
+pspec_type_init :: Text -> Parser Text
+pspec_type_init p = return $ "haskell_gi_pspec_type_init_" <> p
