Доступ C глобальная переменная 'errno' от C#

Действительно ли возможно получить доступ к "errno" переменной в C# когда P/Invoking? Это подобно Win32 GetLastError ().

9
задан joemoe 20 March 2010 в 16:30
поделиться

3 ответа

Я почти уверен, что способ есть, но, вероятно, это плохая идея. Как вы можете гарантировать, что среда выполнения не вызвала какую-либо функцию CRT во время своей внутренней обработки, которая повлияла на errno ?

По той же причине вам не следует напрямую вызывать GetLastError . . DllImportAttribute предоставляет свойство SetLastError , чтобы среда выполнения знала, что нужно немедленно зафиксировать последнюю ошибку и сохранить ее в месте, которое управляемый код может прочитать с помощью Marshal.GetLastWin32Error .

Я думаю, что наиболее надежная вещь, которую вы могли бы сделать в этом случае, - это создать C DLL, которая выполняет как фактическую работу C, так и захват errno .(Обратите внимание, что простое написание оболочки вокруг захвата errno по-прежнему вызовет проблемы, упомянутые выше.)

8
ответ дан 3 November 2019 в 00:00
поделиться

Да, это возможно - GetLastError делает именно это. Однако, как указал двоичный кодировщик, вы не должны делать это напрямую - вместо этого установите SetLastError на вашем DllImport , чтобы это выполнялось и кэшировалось автоматически (и во избежание проблем с многопоточностью или запуска во время выполнения функции, изменяющие значение errno ) - затем при вызове функции P / Invoked проверяйте ее статус возврата и, если она показывает состояние ошибки - бросайте Win32Exception , которая считывает значение последняя ошибка автоматически. Да, даже на Mono в Linux.

2
ответ дан 3 November 2019 в 00:00
поделиться

Решением является использование SetLastError в DllImport . Это заставит среду выполнения сохранить последнюю ошибку, чтобы к ней можно было получить доступ из Marshal.GetLastWin32Error .

Есть две проблемы с прямым вызовом GetLastError :

  • Среда выполнения может работать через некоторое время после возврата PInvoke, прежде чем вы сможете получить последнюю ошибку.
  • Несколько потоков .NET могут находиться на такая же родная нить. Это может привести к тому, что 2 потока .NET будут выполнять PInvokes, а собственные библиотеки, не зная ничего лучше, перезапишут последнюю ошибку. Итак, поток A в .NET получает последнюю ошибку потока B (потенциально).
2
ответ дан 3 November 2019 в 00:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: