static void BlittableFunctionPointers() { Console.WriteLine($"Running {nameof(BlittableFunctionPointers)}..."); IntPtr mod = NativeLibrary.Load(NativeFunctions.GetFullPath()); const int a = 7; const int expected = a * 2; { var cb = NativeLibrary.GetExport(mod, "DoubleInt").ToPointer(); Assert.Throws <NotImplementedException>(() => CallFunctionPointers.CallUnmanagedIntInt(cb, a)); } { var cb = NativeLibrary.GetExport(mod, "DoubleIntCdecl").ToPointer(); int b = CallFunctionPointers.CallUnmanagedCdeclIntInt(cb, a); Assert.AreEqual(b, expected); } { var cb = NativeLibrary.GetExport(mod, "DoubleIntStdcall").ToPointer(); int b = CallFunctionPointers.CallUnmanagedStdcallIntInt(cb, a); Assert.AreEqual(b, expected); } }
static void BlittableFunctionPointers() { Console.WriteLine($"Running {nameof(BlittableFunctionPointers)}..."); IntPtr mod = NativeLibrary.Load(NativeFunctions.GetFullPath()); var cbDefault = NativeLibrary.GetExport(mod, "DoubleInt").ToPointer(); var cbCdecl = NativeLibrary.GetExport(mod, "DoubleIntCdecl").ToPointer(); var cbStdcall = NativeLibrary.GetExport(mod, "DoubleIntStdcall").ToPointer(); const int a = 7; const int expected = a * 2; { // No modopt Console.WriteLine($" -- unmanaged"); int b = CallFunctionPointers.CallUnmanagedIntInt(cbDefault, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged cdecl"); int b = CallFunctionPointers.CallUnmanagedCdeclIntInt(cbCdecl, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged stdcall"); int b = CallFunctionPointers.CallUnmanagedStdcallIntInt(cbStdcall, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged modopt(cdecl)"); int b = CallFunctionPointers.CallUnmanagedIntInt_ModOptCdecl(cbCdecl, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged modopt(stdcall)"); int b = CallFunctionPointers.CallUnmanagedIntInt_ModOptStdcall(cbStdcall, a); Assert.Equal(expected, b); } { // Value in modopt is not a recognized calling convention Console.WriteLine($" -- unmanaged modopt unrecognized"); int b = CallFunctionPointers.CallUnmanagedIntInt_ModOptUnknown(cbDefault, a); Assert.Equal(expected, b); } { // Multiple modopts with calling conventions Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(cdecl)"); var ex = Assert.Throws <InvalidProgramException>( () => CallFunctionPointers.CallUnmanagedIntInt_ModOptStdcall_ModOptCdecl(cbCdecl, a)); Assert.Equal("Multiple unmanaged calling conventions are specified. Only a single calling convention is supported.", ex.Message); } { Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(unrecognized)"); int b = CallFunctionPointers.CallUnmanagedIntInt_ModOptStdcall_ModOptUnknown(cbStdcall, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged cdecl modopt(stdcall)"); int b = CallFunctionPointers.CallUnmanagedCdeclIntInt_ModOptStdcall(cbCdecl, a); Assert.Equal(expected, b); } { Console.WriteLine($" -- unmanaged stdcall modopt(cdecl)"); int b = CallFunctionPointers.CallUnmanagedStdcallIntInt_ModOptCdecl(cbStdcall, a); Assert.Equal(expected, b); } }