public static void TestPInvokeMarkedWithUnmanagedCallersOnly() { Console.WriteLine($"Running {nameof(TestPInvokeMarkedWithUnmanagedCallersOnly)}..."); // Call P/Invoke directly Assert.Throws <NotSupportedException>(() => CallingUnmanagedCallersOnlyDirectly.CallPInvokeMarkedWithUnmanagedCallersOnly(0)); // Call P/Invoke via reflection var method = typeof(CallingUnmanagedCallersOnlyDirectly).GetMethod(nameof(CallingUnmanagedCallersOnlyDirectly.PInvokeMarkedWithUnmanagedCallersOnly)); Assert.Throws <NotSupportedException>(() => method.Invoke(null, BindingFlags.DoNotWrapExceptions, null, new[] { (object)0 }, null)); // Call P/Invoke as a function pointer /* * void TestPInvokeMarkedWithUnmanagedCallersOnly_Throws() * { * .locals init (native int V_0) * IL_0000: nop * IL_0001: ldftn int InvalidCSharp.CallingUnmanagedCallersOnlyDirectly::PInvokeMarkedWithUnmanagedCallersOnly(int32) * IL_0007: stloc.0 * * IL_0008: ldc.i4 1234 * IL_000d: ldloc.0 * IL_000e: calli int32 stdcall(int32) * * IL_0014: ret * } */ DynamicMethod testUnmanagedCallersOnly = new DynamicMethod("TestPInvokeMarkedWithUnmanagedCallersOnly_Throws", typeof(int), null, typeof(Program).Module); ILGenerator il = testUnmanagedCallersOnly.GetILGenerator(); il.DeclareLocal(typeof(IntPtr)); il.Emit(OpCodes.Nop); // Get native function pointer of the callback il.Emit(OpCodes.Ldftn, method); il.Emit(OpCodes.Stloc_0); int n = 1234; il.Emit(OpCodes.Ldc_I4, n); il.Emit(OpCodes.Ldloc_0); il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, typeof(int), new Type[] { typeof(int) }); il.Emit(OpCodes.Ret); IntNativeMethodInvoker testNativeMethod = (IntNativeMethodInvoker)testUnmanagedCallersOnly.CreateDelegate(typeof(IntNativeMethodInvoker)); Assert.Throws <NotSupportedException>(() => testNativeMethod()); }
public static void NegativeTest_ViaDelegate() { Console.WriteLine($"Running {nameof(NegativeTest_ViaDelegate)}..."); // Try invoking method directly Assert.Throws <NotSupportedException>(() => { CallAsDelegate(); }); // Local function to delay exception thrown during JIT void CallAsDelegate() { Func <int, int> invoker = CallingUnmanagedCallersOnlyDirectly.GetDoubleDelegate(); invoker(0); } }