public static void RunWindows()
        {
            string arch;

            // Detect the process architecture
            switch (RuntimeInformation.ProcessArchitecture)
            {
            case Architecture.X86:
                // Workaround for a detection issue. If x86 is detected, but IntPtr is 8 bytes long, we're on x64
                // See https://github.com/dotnet/corefx/issues/25267
                if (IntPtr.Size == 8)
                {
                    arch = "x64";
                }
                else
                {
                    arch = "x86";
                }
                break;

            case Architecture.X64:
                arch = "x64";
                break;

            default:
                throw new PlatformNotSupportedException("Only x86 and x64 are supported at the moment");
            }

            Console.WriteLine(arch);

            // Load the correct library
            var projectDir = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))));
            var handle     = WindowsInterop.LoadLibrary(Path.Combine(projectDir, "nativeLibrary", "build", arch, "nativeLibrary.dll"));

            if (handle == IntPtr.Zero)
            {
                Console.Error.WriteLine("Failed to load native library");
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            try
            {
                // Locate the "triggerCallback" function. This function just calls the callback with some parameters.
                var procAddress = WindowsInterop.GetProcAddress(handle, "triggerCallback");
                if (procAddress == IntPtr.Zero)
                {
                    Console.Error.WriteLine("Failed to locate the triggerCallback function.");
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                var triggerCallback = Marshal.GetDelegateForFunctionPointer <NativeLibrary.TriggerCallback>(procAddress);

                triggerCallback(WindowsCallback);
            }
            finally
            {
                WindowsInterop.FreeLibrary(handle);
            }
        }
Beispiel #2
0
        public static void WindowsCallback(string format, IntPtr args)
        {
            // This implementation is pretty straightforward. The IntPtr can be passed to the functions and can be reused.
            var byteLength = WindowsInterop._vscprintf(format, args) + 1;
            var utf8Buffer = Marshal.AllocHGlobal(byteLength);

            try
            {
                WindowsInterop.vsprintf(utf8Buffer, format, args);

                Console.WriteLine(Utf8ToString(utf8Buffer));
            }
            finally
            {
                Marshal.FreeHGlobal(utf8Buffer);
            }
        }