0

I learned that we can get a pointer to an array by GCHandle.AddrOfPinnedObject, and that the pointer points to the first element of the array. It is often used to pass an array to C APIs.

But the documentation of the method doesn't mention that it returns a pointer to the first element of an array. The method returns the address of an object as described in the document, but it seems that the method doesn't guarantee that it returns an address of the first element of an array.

So I guess, it depends on the implementation of the Array class. The pointer returned by AddrOfPinnedObject could point to the Length field or something internal data, depending on the implementation. Is it correct?

Shigure
  • 373
  • 4
  • 13
  • if the address doesn't need to last longer than the P/Invoke call, you could always just cover your bases with `fixed` instead - that *does* explicitly give the address of the first element – Marc Gravell Jun 27 '19 at 16:18
  • @MarcGravell Thanks. I know `fixed` statement, and there is also `Marshal.UnsafeAddrOfPinnedArrayElement`. I'm just curious about `GCHandle.AddrOfPinnedObject` because it seems many people use it to get the address of an array. – Shigure Jun 27 '19 at 16:31
  • Sure, they could have documented this. I'd assume it intentionally wasn't, just not the best way to do this. The pinvoke marshaller already pins and it does it best. Otherwise the "principle of least surprise" at work. When you look [at the code](https://github.com/dotnet/coreclr/blob/ef1e2ab328087c61a6878c1e84f4fc5d710aebce/src/vm/marshalnative.cpp#L786) then you can see that System.String gets the same treatment. – Hans Passant Jun 27 '19 at 18:47

0 Answers0