public static void TestPInvokeMarkedWithUnmanagedCallersOnly() { Console.WriteLine($"Running {nameof(TestPInvokeMarkedWithUnmanagedCallersOnly)}..."); // Call P/Invoke directly var pInvokeWrapperMethod = GetCallingUnmanagedCallersOnlyDirectlyType().GetMethod("CallPInvokeMarkedWithUnmanagedCallersOnly"); Assert.Throws <NotSupportedException>(() => pInvokeWrapperMethod.Invoke(null, BindingFlags.DoNotWrapExceptions, null, new[] { (object)0 }, null)); // Call P/Invoke via reflection var method = GetCallingUnmanagedCallersOnlyDirectlyType().GetMethod("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 TestUnmanagedCallersOnlyViaUnmanagedCalli_ThrowException() { Console.WriteLine($"Running {nameof(TestUnmanagedCallersOnlyViaUnmanagedCalli_ThrowException)}..."); /* * void UnmanagedCallersOnlyViaUnmanagedCalli_ThrowException() * { * .locals init (native int V_0) * IL_0000: nop * IL_0001: ldftn int CallbackViaUnmanagedCalliThrows(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("UnmanagedCallersOnlyViaUnmanagedCalli_ThrowException", 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, typeof(Program).GetMethod(nameof(CallbackViaUnmanagedCalliThrows))); 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)); try { testNativeMethod(); Assert.Fail($"Function {nameof(CallbackViaUnmanagedCalliThrows)} should throw"); } catch (Exception e) { Assert.AreEqual(CallbackThrowsErrorCode, e.HResult); } }
public static void TestUnmanagedCallersOnlyViaUnmanagedCalli() { Console.WriteLine($"Running {nameof(TestUnmanagedCallersOnlyViaUnmanagedCalli)}..."); /* * void UnmanagedCallersOnlyViaCalli() * { * .locals init (native int V_0) * IL_0000: nop * IL_0001: ldftn int CallbackViaUnmanagedCalli(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("UnmanagedCallersOnlyViaUnmanagedCalli", 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, typeof(Program).GetMethod(nameof(CallbackViaUnmanagedCalli))); 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)); int expected = DoubleImpl(n); Assert.AreEqual(expected, testNativeMethod()); }
public static int TestNativeCallableValid() { /* * void TestNativeCallable() * { * .locals init ([0] native int ptr) * IL_0000: nop * IL_0002: ldftn int32 CallbackMethod(int32) * * IL_0012: stloc.0 * IL_0013: ldloc.0 * IL_0014: ldc.i4 100 * IL_0019: call bool NativeMethods::CallNativeAdd(native int, int) * IL_001e: pop * IL_001f: ret * } */ DynamicMethod testNativeCallable = new DynamicMethod("TestNativeCallable", typeof(int), null, typeof(Program).Module); ILGenerator il = testNativeCallable.GetILGenerator(); il.DeclareLocal(typeof(IntPtr)); il.Emit(OpCodes.Nop); // Get native function pointer of the callback il.Emit(OpCodes.Ldftn, typeof(Program).GetMethod("ManagedAddCallback")); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloc_0); // return 111+100 il.Emit(OpCodes.Ldc_I4, 111); il.Emit(OpCodes.Call, typeof(NativeMethods).GetMethod("CallManagedAdd")); il.Emit(OpCodes.Ret); IntNativeMethodInvoker testNativeMethod = (IntNativeMethodInvoker)testNativeCallable.CreateDelegate(typeof(IntNativeMethodInvoker)); if (testNativeMethod() != 211) { return(0); } return(100); }