[Gtk-sharp-list] Access Violations with Mono.Cairo on Windows
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
More information about the Gtk-sharp-list