Skip to content

Instantly share code, notes, and snippets.

@tannergooding
Created January 22, 2021 17:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tannergooding/9d763b4320c3ceeabee3a2d1a722ba01 to your computer and use it in GitHub Desktop.
Save tannergooding/9d763b4320c3ceeabee3a2d1a722ba01 to your computer and use it in GitHub Desktop.
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*<void> action) => action();
// Same as `delegate*<void>
// public static void Call(delegate* managed<void> action) => action();
// error CS8889: The target runtime doesn't support extensible or runtime-environment default calling conventions.
// public static void Call(delegate* unmanaged<void> action) => action();
public static void Call(delegate* unmanaged[Stdcall]<void> action) => action();
public static delegate*<void> GetManagedAction() => &MyManagedAction;
public static delegate* unmanaged[Stdcall]<void> GetStdcallAction()
=> (delegate* unmanaged[Stdcall]<void>)Marshal.GetFunctionPointerForDelegate(MyStdcallAction);
// error CS8786: Calling convention of 'Net5PlusOnly.MyDefaultAction()' is not compatible with 'Standard'.
// public static delegate* unmanaged[Stdcall]<void> 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<void> action) => action();
public static delegate* unmanaged<void> GetDefaultAction() => &MyDefaultAction;
// error CS8786: Calling convention of 'Net5PlusOnly.MyStdcallAction()' is not compatible with 'Unmanaged'.
// public static delegate* unmanaged<void> GetDefaultAction2() => &MyStdcallAction;
public static delegate* unmanaged[Stdcall]<void> GetStdcallAction() => &MyStdcallAction;
// error CS8786: Calling convention of 'Net5PlusOnly.MyDefaultAction()' is not compatible with 'Standard'.
// public static delegate* unmanaged[Stdcall]<void> GetStdcallAction2() => &MyDefaultAction;
[UnmanagedCallersOnly]
public static void MyDefaultAction() { }
[UnmanagedCallersOnly(CallConvs = new Type[] { typeof(CallConvStdcall) })]
public static void MyStdcallAction() { }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment