我有在C#中声明的COM方法签名:
void Next(ref int pcch,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
char[] pchText);
我这样称呼它:
int cch = 100;
var buff = new char[cch];
com.Next(ref cch, buff);
.NET互操作层是否首先将整个数组复制到一个临时的非托管内存缓冲区,然后再复制回去?还是数组自动固定并通过引用传递?
为了尝试,我在COM对象(C ++)中这样做:
*pcch = 1;
pchText[0] = L'A';
pchText[1] = L'\x38F'; // 'Ώ'
'Ώ'
当我返回时签buff[1]
入C#时,我确实会回来。但是我不认为这有力地证明了阵列是固定的,而不是来回复制的。
让我们做一个小实验。首先,让我们将您的COM方法更改为如下形式(在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#方法签名:
void Next(ref uint pcch, out IntPtr addr,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
char[] pbuff);
最后,像这样测试它:
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
是true
。因此,显然数组在传递给COM时确实会固定而不是复制。
就是说,我找不到任何文档将其描述为CLR实现的硬性要求。例如,对于Mono,这可能是正确的,也可能不是。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句