[Gtk-sharp-list] Access Violations with Mono.Cairo on Windows

Michael Hutchinson m.j.hutchinson at gmail.com
Wed Dec 30 15:46:24 EST 2009

On Wed, Dec 30, 2009 at 9:21 AM, Andy Selvig <ajselvig at gmail.com> wrote:
> It is marked as obsolete (at least it is in whatever version I'm using on
> Linux), but from the code you linked to it simply calls the valid
> constructor anyway, so it should do the exact same thing.
> Plus, it does work initially. It takes a couple seconds to fail, but before
> that, it renders exactly the way it should.

Ah, I missed the base call.

OK, so the likely problem here is that the underlying native code of
the imagesurface expects to keep a reference to the  byte[] that's
passed to it. The delay implies that it's marshalled as a pointer
directly into the managed byte[], and .NET's compacting GC is moving
the byte[] afterwards. Things that you pass into p/invokes are pinned
for the duration of the call, but not afterwards.

You should probably use a GCHandle to pin the byte[]:
var gch = new GCHandle (imageData, GCHandleType.Pinned);
and make sure you gch.Free() when you dispose the surface.

Alternatively, you could modify Mono.Cairo to:
* use Marshal.AllocHGlobal to malloc some unmanaged memory, and get an
IntPtr to it
* use Marshal.Copy to mcpy the byte[] to the new memory
* change the p/invoke signature to use a IntPtr instead of a byte[]
* use Marshal.FreeHGlobal to free the memory when the surface is disposed

Michael Hutchinson

More information about the Gtk-sharp-list mailing list