我想知道在进行pinvokes时使用ref return与使用指针有什么区别。我正在调用的本机方法签名是:
typedef struct Buffer {
const void* Data;
size_t Length;
} Buffer;
__declspec(dllexport) extern Buffer* GetNewBuffer();
在C#端,我将Buffer
结构一对一映射。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Buffer
{
public IntPtr Data;
public UIntPtr Length;
}
我还有两个静态方法,它们调用实现的本地函数,如下所示:
[DllImport("testlib", EntryPoint = "GetNewBuffer")]
public static extern unsafe Buffer* GetNewBufferPointer();
[DllImport("testlib", EntryPoint = "GetNewBuffer")]
public static extern ref Buffer GetNewBufferReference();
这两种方法可编译为以下MSIL:
.method public hidebysig static pinvokeimpl("testlib" as "GetNewBuffer" winapi)
valuetype TestInterop.Buffer* GetBufferPointer () cil managed preservesig
{
} // end of method Native::GetBufferPointer
.method public hidebysig static pinvokeimpl("testlib" as "GetNewBuffer" winapi)
valuetype TestInterop.Buffer& GetBufferReference () cil managed preservesig
{
} // end of method Native::GetBufferReference
使用这些方法并访问返回的struct成员看起来像这样:
unsafe
{
Buffer* bufferPointer = Native.GetBufferPointer();
var dataFromPointer = bufferPointer->Data;
}
ref Buffer bufferReference = ref Native.GetBufferReference();
var dataFromReference = bufferReference.Data;
除了用于存储返回值和访问其成员的语法不同之外,这两种方法之间是否还有其他区别?当使用带pinvoke的ref return时,GC是否执行我应注意的任何特殊操作?