通过PInvoke传递托管byte []数组以由Win32填充时,是否需要固定?

时间:2010-02-07 21:32:43

标签: c# .net visual-studio clr pinvoke

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

3 个答案:

答案 0 :(得分:35)

简答:不,在这种情况下不需要钉扎

更长的答案:

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

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

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

答案 1 :(得分:3)

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

此页面http://msdn.microsoft.com/en-us/library/aa719896(VS.71).aspx设法继续进行,而没有明确说明编组程序在从托管到非托管的调用期间将数组固定,但如果编组器没有,那么它所描述的大部分内容将无法工作销。

答案 2 :(得分:0)

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