Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过PInvoke传递托管字节[]数组以由Win32填充时,是否需要将其固定?_C#_.net_Visual Studio_Clr_Pinvoke - Fatal编程技术网

C# 通过PInvoke传递托管字节[]数组以由Win32填充时,是否需要将其固定?

C# 通过PInvoke传递托管字节[]数组以由Win32填充时,是否需要将其固定?,c#,.net,visual-studio,clr,pinvoke,C#,.net,Visual Studio,Clr,Pinvoke,假设您正在调用将填充字节数组的Win32函数。创建一个大小为32的空数组。然后将其传递给Win32函数以填充int,然后在托管代码中使用它。在分配字节数组和Win32函数填充字节数组之间,是否存在移动或覆盖字节数组的可能性?很抱歉回答我自己的问题,但我相信如果该类型是可blittable的,如byte[]所示,那么在运行时封送时,该数组将被固定,所以不需要钉住。另一个时间点上的对象会有所不同。如果我错了,请纠正我。简短回答:不,在这种情况下不需要钉住 详细回答: 当托管对象跨越PInvoke边界

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

很抱歉回答我自己的问题,但我相信如果该类型是可blittable的,如byte[]所示,那么在运行时封送时,该数组将被固定,所以不需要钉住。另一个时间点上的对象会有所不同。如果我错了,请纠正我。

简短回答:不,在这种情况下不需要钉住

详细回答:

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

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

引用-

根据msdn,非托管代码只能写入通过引用传递的数组。因此,如果要在非托管端填充数组参数[out]或[in,out],则必须声明该数组参数


这个页面可以继续下去,但从来没有明确指出在从托管到非托管的调用过程中,封送拆收器会固定数组,但是如果封送拆收器不固定数组,它所描述的大部分内容都不会起作用。

在C#中固定字节[]的最佳方法是什么?固定字节[]在
不安全
代码块中使用
固定
关键字。看@Reed:我想他就在这里。marshaller代码将在从managaged调用到本机的过程中固定数组,因此,如果您希望在其他时间在本机代码中引用该数组,则只需显式固定该数组。好的,那么问题是当Win32调用未立即返回时会发生什么?例如,调用ReadFile(),使用重叠I/O和手动重置事件?在执行I/O操作时,调用立即返回。在这种情况下是否需要固定字节数组?如何知道本机库是否正在缓存arrayWell?我应该先读取链接,因为它提供了ReadFileEx和重叠I/O作为您需要锁定的示例。您所说的“本机代码缓存托管指针”是什么意思?这是否意味着在调用本机代码(提供指针)之后,在后续调用中使用先前提供的指针?(指向引用的链接已断开…)