C# 7.3 ref возврат с pinvoke
Я хотел бы знать, в чем разница при использовании ref return по сравнению с указателем при выполнении pinvokes. Подпись нативного метода, которую я вызываю:
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
Использование этих методов и доступ к возвращенным элементам структуры будет выглядеть примерно так:
unsafe
{
Buffer* bufferPointer = Native.GetBufferPointer();
var dataFromPointer = bufferPointer->Data;
}
ref Buffer bufferReference = ref Native.GetBufferReference();
var dataFromReference = bufferReference.Data;
Есть ли разница между этими двумя методами, кроме разного синтаксиса, используемого для хранения возвращаемого значения и доступа к его элементам? При использовании ref return с pinvoke, GC делает что-то особенное, о чем я должен знать?