Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pinning Array of .NET objects

I would like to pin an array of .NET objects (including the objects) in order to allow a native function to do some processing on the objects. As far as I understood, GCHandle.Alloc() does not allow me to do this, because such an array contains references (and the objects might also contain references) which are not blittable.

Is there any other option to achieve this? I would be okay with very hack-y suggestions or ones that require Mono.

like image 201
user1622959 Avatar asked Nov 08 '12 16:11

user1622959


People also ask

What is pinning object in C#?

Many wish to access the memory location if they have unmanaged code that references to a C# object they've built. Now they can accomplish this with confidence if they pin the object. But what exactly is pinning an object? In simple words, a pinned object is nothing but an object that has a specific memory location.

How do you assign an array of objects in C#?

You declare an array by specifying the type of its elements. If you want the array to store elements of any type, you can specify object as its type. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from Object.

Can you have an array of objects in C#?

As we know that, we can create array of integers, floats, doubles etc. Similarly we can create array of objects. By using this array of objects, we can access methods of class with each object (which are the elements of that array).

What is pinning object in asp net?

A pinned object is one that cannot be moved around by the garbage collector, meaning its address has to be kept the same because someone else, usually some piece of non managed code, depends upon the object being at a definite memory address. Usually the garbage collector has freedom to relocate objects in memory.


1 Answers

Arrays in .NET are represented in contiguous memory. So that means that in memory, after element 0, element 1 will come directly after the previous element, and so on.

If you pin the array with GCHandle.Alloc, then that means the entire list of elements is pinned in memory as well, and you can process that in unmanaged code.

However, as you've mentioned, it only makes sense if the type is a blittable type (technically, this is not true, it's if the type is able to be marshaled to unmanaged code, although there's a lot of overlap here between the blittable primary types and stuff that the P/Invoke/COM Interop layers handle automatically).

So if you have an array of value types, you can call GCHandle.Alloc and it will pin the array for you. However, the P/Invoke layer already does this for you, so you shouldn't be concerned with this.

If your array is full of references, then marshalling it to unamanged code doesn't make sense anyways; even if you pin every reference, the unmanaged code wouldn't know what to do with that reference in memory, as the type system doesn't support the .NET type that the reference is pointing to in memory.

If the class in .NET is really a wrapper/.NET representation of a native structure, then you're better off creating an array of that structure in .NET, copying all the data into it, and then sending it to your native code.

Or, you could write your class in C++/cli to facilitate the access of the .NET members in native code.

like image 185
casperOne Avatar answered Sep 30 '22 17:09

casperOne