using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; public unsafe class NetStandardPlus { [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate void MyStdcallDelegate(); public static void Call(delegate* action) => action(); // Same as `delegate* // public static void Call(delegate* managed action) => action(); // error CS8889: The target runtime doesn't support extensible or runtime-environment default calling conventions. // public static void Call(delegate* unmanaged action) => action(); public static void Call(delegate* unmanaged[Stdcall] action) => action(); public static delegate* GetManagedAction() => &MyManagedAction; public static delegate* unmanaged[Stdcall] GetStdcallAction() => (delegate* unmanaged[Stdcall])Marshal.GetFunctionPointerForDelegate(MyStdcallAction); // error CS8786: Calling convention of 'Net5PlusOnly.MyDefaultAction()' is not compatible with 'Standard'. // public static delegate* unmanaged[Stdcall] GetStdcallAction2() => &MyDefaultAction; public static void MyManagedAction() { } // error CS0246: The type or namespace name 'UnmanagedCallersOnly' could not be found (are you missing a using directive or an assembly reference?) // -- This requires runtime support, it's not as simple as just defining the attribute // [UnmanagedCallersOnly] // public static void MyDefaultAction() { } // This needs to be kept alive while native has a reference public static MyStdcallDelegate MyStdcallAction = MyManagedAction; } public unsafe class Net5PlusOnly { public static void Call(delegate* unmanaged action) => action(); public static delegate* unmanaged GetDefaultAction() => &MyDefaultAction; // error CS8786: Calling convention of 'Net5PlusOnly.MyStdcallAction()' is not compatible with 'Unmanaged'. // public static delegate* unmanaged GetDefaultAction2() => &MyStdcallAction; public static delegate* unmanaged[Stdcall] GetStdcallAction() => &MyStdcallAction; // error CS8786: Calling convention of 'Net5PlusOnly.MyDefaultAction()' is not compatible with 'Standard'. // public static delegate* unmanaged[Stdcall] GetStdcallAction2() => &MyDefaultAction; [UnmanagedCallersOnly] public static void MyDefaultAction() { } [UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })] public static void MyStdcallAction() { } }