visual-studio 当通过PInvoke传递托管字节[]数组以供Win32填充时,是否需要固定?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2218444/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 11:31:25  来源:igfitidea点击:

When passing a managed byte[] array through PInvoke to be filled in by Win32, does it need to be pinned?

c#.netvisual-studioclrpinvoke

提问by Leeks and Leaks

Suppose you're calling a Win32 function that will fill in your byte array. You create an array of size 32, empty. Then pass it in to the Win32 function to be filled int, and use it later in your managed code. Does there exist the chance that the byte array might be moved or overwritten in between the time it was allocated and it is filled in by the Win32 function?

假设您正在调用一个 Win32 函数,它将填充您的字节数组。您创建了一个大小为 32 的空数组。然后将其传递给要填充为 int 的 Win32 函数,并稍后在您的托管代码中使用它。在分配字节数组和由 Win32 函数填充它之间,是否有可能移动或覆盖字节数组?

回答by JaredPar

Short Answer: No, pinning is not necessary in this case

简短回答:不,在这种情况下不需要固定

Longer Answer:

更长的答案:

The CLR will automatically pin references to managed objects when the cross the PInvoke boundary. As soon as the PInvoke function exits the reference will be unpinned. So in situations like having a native function fill a byte[]no manually pinning is necessary because the object is only used by native code during the function call.

当跨越 PInvoke 边界时,CLR 将自动固定对托管对象的引用。一旦 PInvoke 函数退出,引用将被取消固定。因此,在具有本机函数填充的情况下,byte[]不需要手动固定,因为该对象仅在函数调用期间由本机代码使用。

Manually pinning of the array becomes necessary if the native code caches the managed pointer. When this happens you must manually pin the array until the native code no longer needs the pointer. In this case I presume the pointer is not cached hence it's not necessary to pin

如果本机代码缓存托管指针,则必须手动固定数组。发生这种情况时,您必须手动固定数组,直到本机代码不再需要该指针。在这种情况下,我认为指针没有被缓存,因此没有必要固定

Reference - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2

参考 - http://msdn.microsoft.com/en-us/magazine/cc163910.aspx#S2

回答by John Knoeller

according to msdn Marshaling Arrays of Typesonly an array passed by reference can be written to by unmanaged code. So it appears that you mustdeclare the array parameter [out] or [in,out] if you want to fill it in on the unmanaged side.

根据 msdn Marshaling Arrays of Types,只有通过引用传递的数组才能由非托管代码写入。因此,如果要在非托管端填充它,则似乎必须声明数组参数 [out] 或 [in,out]。

This page http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspxmanages to go on and on without ever explicitly saying that the marshaller pins the arrays during the call from managed to unmanaged, but much of what it describes wouldn't work if the marshaller didn't pin.

这个页面http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx设法继续下去,而没有明确说明编组器在从托管到非托管的调用期间固定阵列,但如果编组员没有固定,它所描述的大部分内容都将不起作用。

回答by Leeks and Leaks

Sorry to answer my own question but I believe if the type is blittable, as byte[] is, then the array would be pinned while being marshalled by the runtime, so no pinning would be needed. An object on the other time would be different. Please correct me if I'm wrong.

很抱歉回答我自己的问题,但我相信如果类型是 blittable,就像 byte[] 一样,那么数组将在由运行时编组时被固定,因此不需要固定。另一个时间的对象会有所不同。如果我错了,请纠正我。