
c2hs is calculating the sizeof glib's GValue structure incorrectly (this led to a nasty bug). GValue is defined like this: struct _GValue { /*< private >*/ GType g_type; /* public for GTypeValueTable methods */ union { gint v_int; guint v_uint; glong v_long; gulong v_ulong; gint64 v_int64; guint64 v_uint64; gfloat v_float; gdouble v_double; gpointer v_pointer; } data[2]; }; We used to use this code: allocaGValue :: (GValue -> IO b) -> IO b allocaGValue body = allocaBytes {# sizeof GValue #} $ \gvPtr -> do ... but we eventually discovered that {# sizeof GValue #} was giving us the wrong value, I think it was 8. The right value should be 8+8+4=20. Our current workaround is: allocaGValue :: (GValue -> IO b) -> IO b allocaGValue body = -- c2hs is broken in that it can't handle arrays of compound arrays in the -- sizeof hook allocaBytes ({# sizeof GType #}+ 2* {# sizeof guint64 #}) $ \gvPtr -> do Axel also added this temporary hack so that at least c2hs would report an error rather the giving the wrong answer: --- ../build/gtk2hs-0.9.10/tools/c2hs/c/CTrav.hs 2004-11-21 21:05:27.000000000 +0000 +++ ../build/gtk2hs/tools/c2hs/c/CTrav.hs 2006-04-25 18:53:10.000000000 +0100 @@ -73,7 +73,7 @@ -- isTypedef, simplifyDecl, declrFromDecl, declrNamed, declaredDeclr, declaredName, structMembers, expandDecl, - structName, enumName, tagName, isPtrDeclr, dropPtrDeclr, + structName, enumName, tagName, isArrDeclr, isPtrDeclr, dropPtrDeclr, isPtrDecl, isFunDeclr, structFromDecl, funResultAndArgs, chaseDecl, findAndChaseDecl, checkForAlias, checkForOneAliasName, lookupEnum, lookupStructUnion, @@ -537,6 +537,16 @@ isPtrDeclr (CFunDeclr declr _ _ _) = isPtrDeclr declr isPtrDeclr _ = False +-- checks whether the given declarator defines an object that is an array of +-- some other type (EXPORTED) +-- +-- * difference between arrays and pure pointers is important for size +-- calculations +-- +isArrDeclr :: CDeclr -> Bool +isArrDeclr (CArrDeclr declr _ _) = True +isArrDeclr _ = False + -- drops the first pointer level from the given declarator (EXPORTED) -- -- * the declarator must declare a pointer object --- ../build/gtk2hs-0.9.10/tools/c2hs/gen/GenBind.hs 2005-10-17 21:41:30.000000000 +0100 +++ ../build/gtk2hs/tools/c2hs/gen/GenBind.hs 2006-04-25 18:53:10.000000000 +0100 @@ -1665,6 +1667,8 @@ -- * we make use of the assertion that `extractCompType' can only return a -- `DefinedET' when the declaration is a pointer declaration -- +sizeAlignOf (CDecl specs [(Just declr, _, size)] ats) | isArrDeclr declr = + interr $ "sizeAlignOf: calculating size of constant array not supported." sizeAlignOf cdecl = do ct <- extractCompType cdecl So, that's the temporary solution. Of course it'd be better if we could actually calculate this struct size. This issue of struct sizes (and alignments) is probably an area that needs more testing (and on other arches since eg MS packs bit-fields differently). Perhaps we could write a prog that scans a header file and generates a .chs and .hsc file with {# sizeof #} hooks for every structure. Then we could compare the two (with various headers and on various platforms) and see where the remaining issues are. Using .hsc as a reference would be the right thing here because hsc2hs uses gcc to find the struct size. That same kind of test would also do for struct member offsets. Duncan