[Gtk-sharp-list] Gtk# audit
Rachel Hestilow
hestilow@ximian.com
24 Dec 2002 02:53:19 -0600
--=-xU4xFh+KKVYkqArtcBXt
Content-Type: multipart/mixed; boundary="=-nmkq0FbJMpLT2uK7BT4g"
--=-nmkq0FbJMpLT2uK7BT4g
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable
So, this is mainly for Duncan's benefit, who wanted to do this while he
was on vacation. Basically, I've written up a set of guidelines for
auditing the correctness of the Gtk# API. This is an easy way to
contribute to Gtk#, that doesn't really require anything in the way of
coding. If you're interested in contributing, you probably will want to
coordinate over the list or IRC as to what classes you will be tackling,
lest you duplicate someone else's work...although for auditing,
duplication of effort sometimes helps, rather than hinders. Be sure to
post any metadata patches to the list, and if you have any questions,
feel free to ask.
Thanks!
Rachel
--=-nmkq0FbJMpLT2uK7BT4g
Content-Disposition: inline; filename=gtksharp-audit.txt
Content-Type: text/plain; name=gtksharp-audit.txt; charset=ANSI_X3.4-1968
Content-Transfer-Encoding: quoted-printable
Auditing the Gtk# sources
-------------------------
For the most part, the Gtk# generator is capable of generating correct .NET
APIs without any help at all. However, sometimes there are certain semantic=
s
that it is incapable of inferring from the C sources. In these cases,
metadata is required.
The best way to audit Gtk# is to go through it, class-by-class, and compare
the C# source with the C source and with the C documentation. For each
method in the class, apply the following criteria. If you find the method
needs a metadata addition, either add the metadata before you go on to the
next, or write down the details of what you have found, and then add the
metadata later. Metadata files live in sources/, and are divided up
according to namespace. For example, metadata additions to the Gtk
namespace should go into sources/Gtk.metadata. Remember, many methods are
reexpressed in Gtk# as properties. If you see a property calling a
DllImported method, the same criteria apply to it as for a method.
Things that need metadata
-------------------------
* Array parameters and return values
=20
These are often indistinguishable from pointers. One hint that it may
be an array is that it is a double-pointer (**). However,
some struct arrays may only have one pointer (*). The best way to find
out is to check the documentation.
To tag an array parameter, insert the following metadata rule:
=20
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"param">
<filter level=3D"name">PARAMETERNAME</filter>
<name>array</name>
<value>1</value>
</attribute>
</data>
</rule>
To tag an array return value, insert the following metadata rule:
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"return">
<name>array</name>
<value>1</value>
</attribute>
</data>
</rule>
* GList and GSList return values.
These are easy to identify: Their C type will be either GList* or GSList*=
.
To marshal these, the generator must know what type of data the list
is holding. For parameters, the generator can infer the types
automatically. However, the generator cannot know what type of data
the list is holding if it is a return value. Check the documentation
and sources to determine the data type.
If the list is holding a GObject (or anything derived from a GObject),
Gtk# can infer the type automatically even for return values, and
no metadata is required. However, for structs and basic types,
you need to explicitly specify the equivalent C# type. This should be
a fully qualified typename, including the namespace if it is a class.
For example, a list of PangoLayoutLine* has an element_type of
Pango.LayoutLine, while a list of ints has an element_type of int.
To tag a list return value, insert the following metadata rule:
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"return">
<name>element_type</name>
<value>CSHARPTYPE</value>
</attribute>
</data>
</rule>
* Ref-counting return values
Sometimes, methods return GObjects without first increasing their
reference count. This will break Gtk#'s garbage collection. In order
to work around this, Gtk# must manually increase the reference count.
It's difficult to determine whether or not a method needs an extra
reference count. Sometimes the documentation will mention who owns the
returned value. The best indicator is if a method returns the object
directly from a struct field. For example, the source code for
gtk_widget_get_style is as follows:
GtkStyle*
gtk_widget_get_style (GtkWidget *widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
=20
return widget->style;
}
The reference count is not increased on the returned style, so it
needs a metadata directive.
=20
To tag a return value for reference counting, insert the following
metadata rule:
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"return">
<name>needs_ref</name>
<value>1</value>
</attribute>
</data>
</rule>
* Parameters where NULL pointers are allowed
Sometimes, a method allows a parameter to be NULL. Usually it has
a special significance that cannot be worked around. The best way
to determine if a method allows a specific parameter is to make sure
it is not checking for it with a g_return_if_fail or g_return_val_if_fail=
.
For example, if a function checks a parameter like this:
g_return_if_fail (foo !=3D NULL);
Or like this:
g_return_if_fail (GTK_IS_FOO (foo));
Then NULL is NOT allowed, and the default Gtk# behavior is fine. But if
the documentation says NULL is allowed, or if Gtk+ doesn't check for
it, it's probably allowed.
To tag a parameter as allowing NULL, insert the following
metadata rule:
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"param">
<filter level=3D"name">PARAMETERNAME</filter>
<name>null_ok</name>
<value>1</value>
</attribute>
</data>
</rule>
* "Out" parameters
If a C function needs to return multiple values, or if it wants to
return a struct without having to allocate the struct itself, it
will use pointer arguments as return values. These often have the
same signatures as array parameters. Check the documentation, or
check the sources to see if the parameter is being deferenced
and assigned to.
=20
To tag an out parameter, insert the following metadata rule.
<rule>
<class name=3D"CLASSNAME">
<method>METHODNAME</method>
</class>
<data>
<attribute target=3D"param">
<filter level=3D"name">PARAMETERNAME</filter>
<name>pass_as</name>
<value>out</value>
</attribute>
</data>
</rule>
--=-nmkq0FbJMpLT2uK7BT4g--
--=-xU4xFh+KKVYkqArtcBXt
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQA+CCB/apOJdUj74F4RAug0AJ9P6lQtWXl5iZQhP8gLPAbBw9JqiACfULMv
HvILX2iN2D5SJD0+EBums+k=
=lzWq
-----END PGP SIGNATURE-----
--=-xU4xFh+KKVYkqArtcBXt--