huseyin tugrul buyukisik huseyin tugrul buyukisik - 2 months ago 10
C# Question

Exchange pinned array's pointer with an unmanaged memory pointer

I'm pinning and unpinning with:

GCHandle pinArray(object a)
{
return GCHandle.Alloc(a, GCHandleType.Pinned);
}

void unpinArray(GCHandle h)
{
h.Free();
}


before and after an opencl method so array does not move while computing on it. Now I need to exchange backing array pointer with an aligned unmanaged array pointer to have faster read/write operations on it.

But I couldn't find anything like "change value of gchandle backing array pointer" info.

I need something like an "exchange" method:

GCHandle h=pinArray(array);

// how to?
IntPtr oldBackingArray=exchange(h,alignedMallocCSpace(10000000,4096));

// unmanaged operations
copyValues(h,oldBackingArray);
compute(array,...); // only passing with "array" for simplicity everywhere
array[3]=5;
l=array.toList();
compute(array,....);
Console.WriteLine(array[3]);
copyValues(oldBackingArray,h);


freeCSpace(exchange(h,oldBackingArray));

unpinArray(h);


does this need reflection to access and change that variable? There are also many C# methods using those arrays inside compute method so will it give more speed even on C# space too? So I'm tring to let C# to use alignedAlloc space for everything using "array" object until I unpin it.

Answer

You don't need to. The GCHandle relates to managed memory; unmanaged memory does not require any kind of GCHandle. Nor is it possible to talk to that memory as though it is a managed array. Instead, you need to accept that the unmanaged data is a pointer and only a pointer. You can abstract over the top of that to hide these details, but it doesn't change the reality. Fortunately, to the casual observer, talking to a SomeType[] is very similar to talking to a SomeType* - as long as you pass the lengths around yourself.

In the future, the upcoming Span<T> does a great job of unifying pointers and arrays, but that is only experimental at the moment.