P/Invoking 할 때 C#의 "errno"변수에 액세스 할 수 있습니까? 이것은 Win32 GetLastError()와 유사합니다.C에서 전역 변수 'errno'에 액세스
답변
나는 방법이 있다는 것이 확실하지만, 아마도 나쁜 생각입니다. errno
에 영향을 준 내부 처리 중 런타임에서 CRT 기능을 호출하지 않았다는 것을 어떻게 보증 하시겠습니까?
같은 이유로 GetLastError
을 직접 호출해서는 안됩니다. DllImportAttribute
은 SetLastError
속성을 제공하므로 런타임은 마지막 오류를 즉시 캡처하여 관리 코드가 읽을 수있는 위치에 Marshal.GetLastWin32Error
을 사용하여 저장할 수 있습니다.
이 경우 가장 강력한 것은 실제로 C 작업과 errno
캡처를 수행하는 C DLL을 만드는 것입니다. (errno
캡쳐 주위에 래퍼를 쓰는 것만으로도 위에 언급 된 문제가 발생합니다.)
예, 가능합니다. 즉, GetLastError
은 정확하게 수행 할 수 있습니다. binarycoder 지적 그러나, 당신이 직접이 작업을 수행해서는 안 - 대신이 수행하고 자동으로 캐시가 귀하의 DllImport
에 SetLastError
을 설정 (및 멀티 스레딩 문제 또는 errno
값을 수정 런타임 호출 기능을 피하기 위해) - 다음의 호출에를 P/호출 된 함수가 반환 상태를 확인하고 오류 조건을 표시하는 경우 Win32Exception
을 throw하면 마지막 오류 값이 자동으로 읽습니다. 예, Linux의 Mono에서도 가능합니다.
이 솔루션은 DllImport
에 SetLastError
을 사용하는 것입니다. 그러면 런타임에 마지막 오류가 저장되어 Marshal.GetLastWin32Error
에서 액세스 할 수 있습니다.
직접 GetLastError
를 호출하는 두 가지 문제가 있습니다 :
-
는
- 여러 .NET 스레드가 같은 기본에 상주 할 수 있습니다 마지막 오류를 얻을 수 있습니다 전에 PInvoke를 한 후 언젠가 할 수있는 런타임 반환
- 실. 이로 인해 2 개의 .NET 스레드가 PInvokes를 수행하고, 네이티브 라이브러리가 더 잘 알지 못하면 마지막 오류를 덮어 씁니다. 따라서 .NET의 스레드 A는 스레드 B의 마지막 오류 (잠재적)를 얻습니다.
당신은'DllImport'에'SetLastError'를 사용하는 구문의 예를 게재 할 수 있습니까? –
그래, 나는이 동의 것입니다. 아마도 C 래퍼에 errno의 값을 반환하는 대상 함수를 설정하는 것이 좋습니다. – supercheetah