Pinning Array of .NET objects

别说谁变了你拦得住时间么 提交于 2019-12-05 06:42:52

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.

m0s

You could take a look at Marshal.AllocHGlobal and Marshal.WriteIntPtr. This is the official way that framework provides to work with unmanaged memory. Not sure if it will be helpful though.

Edit

See also https://stackoverflow.com/a/878147/301525

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!