是否.NET互操作数组复制数据来回,还是它的引脚排列? [英] Does .NET interop copy array data back and forth, or does it pin the array?
问题描述
我有这样的COM方法的签名,在C#中声明:
I have this COM method signature, declared in C#:
void Next(ref int pcch,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
char[] pchText);
我把它称为是这样的:
I call it like this:
int cch = 100;
var buff = new char[cch];
com.Next(ref cch, buff);
请问.NET互操作层的整个数组首先复制到一个临时的非托管内存缓冲区,然后复制回来?抑或是阵列得到自动固定,并通过引用传递?
Does the .NET interop layer first copy the whole array to a temporary unmanaged memory buffer, then copy it back? Or does the array get automatically pinned and passed by reference?
为了尝试,我在COM对象(C ++)这样做:
For the sake of trying, I did this in the COM object (C++):
*pcch = 1;
pchText[0] = L'A';
pchText[1] = L'\x38F'; // 'Ώ'
我得到Ώ
回来时,我检查的buff [1]
在C#在返回。但我不认为这是一个强有力的证明,则数组被固定,而不是复制来回。
I do get 'Ώ'
back when I check buff[1]
in C# upon return. But I don't think this is a strong proof that the array gets pinned, rather than copied back and forth.
推荐答案
让我们做了一个小实验。首先,让我们改变你的COM方法看起来像这样(在C ++中):
Let's do a small experiment. First, let's change your COM method to look like this (in C++):
STDMETHODIMP CComObject::Next(ULONG* pcch, int* addr, OLECHAR* pbuff)
{
pbuff[0] = L'A';
pbuff[1] = L'\x38F';
*addr = (int)pbuff;
*pcch = 1;
return S_OK;
}
然后,改变C#方法签名:
Then, change the C# method signature:
void Next(ref uint pcch, out IntPtr addr,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
char[] pbuff);
最后,测试它是这样的:
Finally, test it like this:
uint cch = 10;
var buff = new char[cch];
IntPtr addr1;
unsafe
{
fixed (char* p = &buff[0])
{
addr1 = (IntPtr)p;
}
}
IntPtr addr2;
com.Next(ref cch, out addr2, buff);
Console.WriteLine(addr1 == addr2);
正如预期的那样, ADDR1 == ADDR2
是真
。因此,显然阵列未得到寄托,而不是当传递给COM复制的。
As expected, addr1 == addr2
is true
. Thus, apparently the array does get pinned rather than copied when passed to COM.
这是说,我找不到任何文件,这将配备以此作为一个CLR实现一个硬性要求。例如,这可能或可能不适合单声道是真实的。
That said, I couldn't find any documentation which would feature this as a hard requirement for a CLR implementation. E.g., this may or may not be true for Mono.
这篇关于是否.NET互操作数组复制数据来回,还是它的引脚排列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!