[Mono-dev] "safe" way about Marshal.UnsafeAddrOfPinnedArrayElement
Kornél Pál
kornelpal at gmail.com
Tue Apr 18 08:13:36 EDT 2006
Hi,
Unsafe code usually means code that uses pointers. But that unsafe code has
to use the fixed statement when accessing objects that can be moved. fixed
statement pins the object so that GC will not move it within the block of
fixed statement. (As far as I know Mono still uses non-moving GC but that
will change in the future and MS.NET uses moving GC.)
Marshal.UnsafeAddrOfPinnedArrayElement is unsafe in addition to pointer
operations because it assumes that the array is already pinned so it won't
(an in fact can't as it has no scope) pin the object so the GC can move it
that can result in invalidation of the returned pointer so has to be used
carefully. (When the array is moved by the GC you can overwrite some other
object that can have unpredictable results.)
Marshal.UnsafeAddrOfPinnedArrayElement is intended to be used with a pinned
GCHandle. (Or alternatively on an array that is already pinned using fixed
statement but in that case you have a pointer to an array element so you
probably don't need this method.)
If you have a non-pinned array you should use fixed statement instead as
Jonathan explained it.
So Marshal.UnsafeAddrOfPinnedArrayElement is even more unsafe than unsafe
code when used on a non-pinned array.
Kornél
----- Original Message -----
From: "Jonathan Pryor" <jonpryor at vt.edu>
To: "GaoXianchao" <gxcmaillist at gmail.com>
Cc: <mono-devel-list at lists.ximian.com>
Sent: Tuesday, April 18, 2006 1:48 PM
Subject: Re: [Mono-dev] "safe" way about
Marshal.UnsafeAddrOfPinnedArrayElement
> On Tue, 2006-04-18 at 12:27 +0800, GaoXianchao wrote:
>> hi all,
>> I'm wrapping epoll api on linux.
>> To pass address of managed struct array to unmanaged code, I use
>> Marshal.UnsafeAddrOfPinnedArrayElement . But the method is "unsafe".
>> Is there a "safe" way to do what the
>> Marshal.UnsafeAddrOfPinnedArrayElement do?
>
> It's "unsafe" because you need to be careful. :-)
>
> An alternative is to use *real* unsafe code, e.g.
>
> FooStruct[] array = ...;
> unsafe {
> fixed (FooStruct* pArray = array) {
> FooStruct* element = &pArray [index];
> }
> }
>
> I'm not entirely sure what your problem is though. "Unsafe" code (like
> the above `unsafe' block) just means that you're possibly executing
> without a net, which could result in memory corruption and abortion of
> the process. :-)
>
> Marshal.UnsafeAddrOfPinnedArrayElement isn't even in an unsafe C#
> context, it just has "Unsafe" in the name.
>
> Here's a hint of truth: ANY time you do a P/Invoke, you're potentially
> doing something unsafe. :-)
>
> (Especially considering that you're invoking external code which could
> really do anything, such as overwrite the entire GC heap, which would
> cause the process an ugly death in the future...)
>
> However, I'm not sure why you need
> Marshal.UnsafeAddrOfPinnedArrayElement in the first place.
> epoll_wait(2) takes a `struct epoll_event' array parameter, so unless
> you wanted to only send a subset of your array, the default marshaling
> rules which convert a managed array to an array pointer should be fine.
>
> - Jon
>
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
More information about the Mono-devel-list
mailing list