C# fixed keyword explaination

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I created a wrapper class for a dll written in C. Will the following code
prevent the "ENTIRE ARRAY" from being moved, not just the first array
element? The Wrapper class will be instantiated in a VB .NET application
which doesn't have the ability to prevent the array from being moved.

Thanks in advance,
coz

public class Wrapper
{
[DllImport("CDll.dll", EntryPoint="CDllRead", SetLastError=true,
CharSet=CharSet.Ansi, ExactSpelling=true,
CallingConvention=CallingConvention.Cdecl)]
private static extern uint CDllRead(uint Offset, uint[] Array, uint
Length);

public uint Read(uint Offset, uint[] Array, uint Length)
{
uint typeSize = (uint)Marshal.SizeOf(typeof(uint));
uint len = Length * typeSize;

unsafe
{
fixed(uint* pArray = Array) // Prevent the GC from moving
the array
{
return CDllRead(m_hRfm, Offset, Array, len);
} // end fixed
}// end unsafe
}// end Read()
}// end Wrapper class
 
To quote from
http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/csspec/html/vclrfcsharpspec_A_6.asp :

An expression of an array-type with elements of an
unmanaged type T, provided the type T* is implicitly
convertible to the pointer type given in the fixed
statement. In this case, the initializer computes the
address of the first element in the array, and the entire
array is guaranteed to remain at a fixed address for the
duration of the fixed statement. The behavior of the fixed
statement is implementation-defined if the array
expression is null or if the array has zero elements.

So yes, your entire array will remain in place while
within the fixed block.

As to your 2nd point, there should be no problem with
calling the code from VB.NET provided you reference an
assembly containing your code.
 
coz,
I have never seen the fixed() notation before, it might be exactly what I am
doing here.

Here is what I would do -

use the GCHandle syntax. It is basically like this.

GCHandle gcHandle = GCHandle.Alloc(Array);
uint* pArray = gcHandle.Target;
CDllRead(m_hRfm, Offset, pArray, len);
gcHandle.Release();

Since Arrays are considered a type in .NET - the entire object of the Array
type is pinned by the GC, not just the first element.

If the fixed() notation is the same as what I have - by all means use that.
Like I said, I have just never seen it before. It is probably in the same
spirit as using().

Take care.
 
Back
Top