Установка точки останова на Marshal.GetLastWin32Error (), кажется, изменяет последний набор ошибок? - PullRequest
2 голосов
/ 20 апреля 2019

Я использую C # с .NET 4.6 в VS2019 на Win10 x64 1809.

При использовании P / Invoke установка точки останова в строке "Marshal.GetLastWin32Error ()", похоже, изменяет последнийустановите код ошибки Win32.

Например:

using System.Runtime.InteropServices;

namespace PInvoke
{
    class Program
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern void SetLastError(
            uint dwErrCode
            );

        static void Main(string[] args)
        {
            int startErr = Marshal.GetLastWin32Error();
            SetLastError(500);
            int endError = Marshal.GetLastWin32Error();

            return;
        }
    }
}

Если я установил точку останова на "return", повторные запуски покажут endError как 500.

Однако, если яустановить точку останова на "int endError = Marshal.GetLastWin32Error ();", повторные запуски показывают end endError как 0.


Похоже, что установка точки останова на любой строке "Marshal.GetLastWin32Error ()" приведет кнеожиданные результаты, как в другой области, в то время как P / Invoking SetupEnumInfSections () я ожидал 259 (ERROR_NO_MORE_ITEMS), но после установки точки останова вместо этого получаю 1008.


  • Я что-то пропускаю, что вызываеттакое поведение в моих проектах?(Я пробовал разные проекты, как личные, так и сторонние, от CodeProject и GitHub, и продолжаю испытывать это поведение)
  • Это ошибка в Visual Studio (я должен сообщить об этом?)
  • Ожидается ли это?(См. Ниже)

Я знал, что вызов Marshal.GetLastWin32Error () должен вызываться сразу после соответствующего вызова API (при условии, что вызов API действительно устанавливает последнюю ошибку,и для вызовов P / Invoke включает «SetLastError = true» в своем декораторе), потому что любой дополнительный вызов может изменить значение последней ошибки.

Однако я не нашел никаких других предупреждений относительноотладка, установка точки останова для Marshal.GetLastWin32Error () и т. д.

Является ли это "недоработкой", о которой должны знать разработчики, пишущие P / Invoke с VS, аналогично следующим вызовам API с помощью GetLastError ()и установка декоратора ("SetLastError = true")?Это может быть «получилось», но если это так, для меня это не сразу очевидно, потому что я ожидаю, что у каждого процесса будет своя последняя ошибка, включая VS (и / или отладчик), но, возможно, он привязан к базовому приложениюкаким-то образом, о котором я не знаю.

...