microsoft / CsWin32

A source generator to add a user-defined set of Win32 P/Invoke methods and supporting types to a C# project.
MIT License
2.05k stars 85 forks source link

Avoid pinning `this` in instance method for struct COM objects #972

Closed Sergio0694 closed 1 year ago

Sergio0694 commented 1 year ago

Overview

I'm trying out CsWin32 with the "allowMarshaling": false mode enabled, which generates blittable struct types for all COM types, instead of interfaces. That is great, but I noticed the generated code is leaving a bit of performance on the table. Specifically:

This is an example, but the same applies to all instance methods across all generated types. Pinning this is actually not needed, because the actual value will always be on native memory (since users would always just receive a pointer to a native COM object).

We can improve this by instead generating:

public uint AddRef()
{
    return ((delegate *unmanaged [Stdcall]<IUnknown*,uint>)lpVtbl[1])((IUnknown*)Unsafe.AsPointer(ref this));
}

Note: this is the same thing also done by eg. TerraFX.Interop.Windows, ComputeSharp and other libraries.

Open questions

Context

AArnott commented 1 year ago

Thanks for the tip.