static void NonblittableFunctionPointers()
    {
        Console.WriteLine($"Running {nameof(NonblittableFunctionPointers)}...");

        IntPtr mod = NativeLibrary.Load(NativeFunctions.GetFullPath());

        const char a        = 'i';
        const char expected = 'I';
        {
            var cb = NativeLibrary.GetExport(mod, "ToUpper").ToPointer();
            Assert.Throws <NotImplementedException>(() => CallFunctionPointers.CallUnmanagedCharChar(cb, a));
        }

        {
            var cb = NativeLibrary.GetExport(mod, "ToUpperCdecl").ToPointer();
            var b  = CallFunctionPointers.CallUnmanagedCdeclCharChar(cb, a);
            Assert.AreEqual(b, expected);
        }

        {
            var cb = NativeLibrary.GetExport(mod, "ToUpperStdcall").ToPointer();
            var b  = CallFunctionPointers.CallUnmanagedStdcallCharChar(cb, a);
            Assert.AreEqual(b, expected);
        }
    }
    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);
        }
    }
Beispiel #3
0
    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);
        }
    }
    static void NonblittableFunctionPointers()
    {
        Console.WriteLine($"Running {nameof(NonblittableFunctionPointers)}...");

        IntPtr mod       = NativeLibrary.Load(NativeFunctions.GetFullPath());
        var    cbDefault = NativeLibrary.GetExport(mod, "ToUpper").ToPointer();
        var    cbCdecl   = NativeLibrary.GetExport(mod, "ToUpperCdecl").ToPointer();
        var    cbStdcall = NativeLibrary.GetExport(mod, "ToUpperStdcall").ToPointer();

        const char a        = 'i';
        const char expected = 'I';

        {
            // No modopt
            Console.WriteLine($" -- unmanaged");
            var b = CallFunctionPointers.CallUnmanagedCharChar(cbDefault, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged cdecl");
            var b = CallFunctionPointers.CallUnmanagedCdeclCharChar(cbCdecl, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged stdcall");
            var b = CallFunctionPointers.CallUnmanagedStdcallCharChar(cbStdcall, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged modopt(cdecl)");
            var b = CallFunctionPointers.CallUnmanagedCharChar_ModOptCdecl(cbCdecl, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged modopt(stdcall)");
            var b = CallFunctionPointers.CallUnmanagedCharChar_ModOptStdcall(cbStdcall, a);
            Assert.AreEqual(expected, b);
        }

        {
            // Value in modopt is not a recognized calling convention
            Console.WriteLine($" -- unmanaged modopt(unrecognized)");
            var b = CallFunctionPointers.CallUnmanagedCharChar_ModOptUnknown(cbDefault, a);
            Assert.AreEqual(expected, b);
        }

        {
            // Multiple modopts with calling conventions
            Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(cdecl)");
            var ex = Assert.Throws <InvalidProgramException>(
                () => CallFunctionPointers.CallUnmanagedCharChar_ModOptStdcall_ModOptCdecl(cbCdecl, a),
                "Multiple modopts with calling conventions should fail");
            Assert.AreEqual("Multiple unmanaged calling conventions are specified. Only a single calling convention is supported.", ex.Message);
        }

        {
            Console.WriteLine($" -- unmanaged modopt(stdcall) modopt(unrecognized)");
            var b = CallFunctionPointers.CallUnmanagedCharChar_ModOptStdcall_ModOptUnknown(cbStdcall, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged cdecl modopt(stdcall)");
            var b = CallFunctionPointers.CallUnmanagedCdeclCharChar_ModOptStdcall(cbCdecl, a);
            Assert.AreEqual(expected, b);
        }

        {
            Console.WriteLine($" -- unmanaged stdcall modopt(cdecl)");
            var b = CallFunctionPointers.CallUnmanagedStdcallCharChar_ModOptCdecl(cbStdcall, a);
            Assert.AreEqual(expected, b);
        }
    }