c# – .NET互操作是否来回复制数组数据,还是固定数组?

我有这个COM方法签名,在C#中声明:
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'; // 'Ώ'

当我在返回时检查C#中的buff [1]时,我会得到’Ώ’.但是我不认为这是一个很强的证据,数组被固定,而不是来回复制.

解决方法

我们来做一个小的实验.首先,让我们改变你的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可能也可能不是这样.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...