[Gtk-sharp-list] Handling errors when generating binding code for asynchronous APIs

Mike Kestner mkestner at gmail.com
Sun Feb 10 11:30:58 EST 2008


On Sun, 2008-02-10 at 15:27 +0100, Philip Van Hoof wrote:

> The GError based error being passed to the callback (which in C is a
> function pointer typedeffed as TnyGetMsgCallback) is not being converted
> to an Exception type.

First, I'm not convinced there's a real advantage to using an exception
for this.  Throwing it is only going to result in the program exiting in
the virtual method marshaler's try/catch or if the user has connected to
GLib.ExceptionManager they'll get the exception there.  So throwing the
exception would just be additional overhead since they can just call the
error handler directly from the method implementation itself.

> My goal is to wrap the "IntPtr err" (which is the GError pointer in C)
> with a factory's Create method that will create me the right managed
> exception:
> 
> public class Tny.ExceptionFactory
> {
> 	static Tny.TException Create (IntPtr gerror) {
> 		// Pseudo, to get the type I'll indeed need to make
> 		// a small piece of glue code in C ...
> 		if (gerror->type == TNY_ERROR_THIS)
> 			return new Tny.ThisException (gerror);
> 		if (gerror->type == TNY_ERROR_THAT)
> 			return new Tny.ThatException (gerror);
> 		...
> 	}
> }

It sounds to me like an error string to enumeration mapping would be
equally as useful.  Regardless, if you are set on creating exceptions
for these, there is already a built in way to hook in a marshaling
method like the above to GAPI.

You will need to alter the type of the parameter to something GAPI
doesn't handle automatically, like TError, using metadata.  Also using
metadata, you need to add a generatable mapping for TError.  Two
possibilities are:

<symbol type="manual" cname="TError" name="Tny.Error"/></add-node>

This assumes the existence of a Tny.Error type which has an IntPtr
Handle prop to marshal to native and a static Tny.Error New (IntPtr)
method to marshal from native.

As an alternative you could use MarshalGen via:

<symbol type="marshal" cname="GdkEvent" name="Gdk.Event"
marshal_type="IntPtr" call_fmt="{0}.Handle" from_fmt="Gdk.Event.GetEvent
({0})" />

Which gives a bit more control over the way you implement your
marshaler.

You can add either of the above symbols to your API file with an
add-node rule in metadata:

<add-node path="/api">...

Mike





More information about the Gtk-sharp-list mailing list