.NET互操作是来回复制数组数据,还是将数组固定?

祖父

我有在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 == addr2true因此,显然数组在传递给COM时确实会固定而不是复制。

就是说,我找不到任何文档将其描述为CLR实现的硬性要求。例如,对于Mono,这可能是正确的,也可能不是。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章