2010-03-21 2 views

답변

7

나는 방법이 있다는 것이 확실하지만, 아마도 나쁜 생각입니다. errno에 영향을 준 내부 처리 중 런타임에서 CRT 기능을 호출하지 않았다는 것을 어떻게 보증 하시겠습니까?

같은 이유로 GetLastError을 직접 호출해서는 안됩니다. DllImportAttributeSetLastError 속성을 제공하므로 런타임은 마지막 오류를 즉시 캡처하여 관리 코드가 읽을 수있는 위치에 Marshal.GetLastWin32Error을 사용하여 저장할 수 있습니다.

이 경우 가장 강력한 것은 실제로 C 작업과 errno 캡처를 수행하는 C DLL을 만드는 것입니다. (errno 캡쳐 주위에 래퍼를 쓰는 것만으로도 위에 언급 된 문제가 발생합니다.)

+0

그래, 나는이 동의 것입니다. 아마도 C 래퍼에 errno의 값을 반환하는 대상 함수를 설정하는 것이 좋습니다. – supercheetah

2

예, 가능합니다. 즉, GetLastError은 정확하게 수행 할 수 있습니다. binarycoder 지적 그러나, 당신이 직접이 작업을 수행해서는 안 - 대신이 수행하고 자동으로 캐시가 귀하의 DllImportSetLastError을 설정 (및 멀티 스레딩 문제 또는 errno 값을 수정 런타임 호출 기능을 피하기 위해) - 다음의 호출에를 P/호출 된 함수가 반환 상태를 확인하고 오류 조건을 표시하는 경우 Win32Exception을 throw하면 마지막 오류 값이 자동으로 읽습니다. 예, Linux의 Mono에서도 가능합니다.

2

이 솔루션은 DllImportSetLastError을 사용하는 것입니다. 그러면 런타임에 마지막 오류가 저장되어 Marshal.GetLastWin32Error에서 액세스 할 수 있습니다.

직접 GetLastError를 호출하는 두 가지 문제가 있습니다 :

  • 여러 .NET 스레드가 같은 기본에 상주 할 수 있습니다 마지막 오류를 얻을 수 있습니다 전에 PInvoke를 한 후 언젠가 할 수있는 런타임 반환
  • 실. 이로 인해 2 개의 .NET 스레드가 PInvokes를 수행하고, 네이티브 라이브러리가 더 잘 알지 못하면 마지막 오류를 덮어 씁니다. 따라서 .NET의 스레드 A는 스레드 B의 마지막 오류 (잠재적)를 얻습니다.
+0

당신은'DllImport'에'SetLastError'를 사용하는 구문의 예를 게재 할 수 있습니까? –