是否.NET互操作数组复制数据来回,还是它的引脚排列? [英] Does .NET interop copy array data back and forth, or does it pin the array?

查看:177
本文介绍了是否.NET互操作数组复制数据来回,还是它的引脚排列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆