Czy jest możliwe uzyskanie dostępu do zmiennej "errno" w języku C#, gdy P/Invoking? Jest to podobne do Win32 GetLastError().Access C zmienna globalna "errno" z C#
Odpowiedz
Jestem dość pewny, że istnieje sposób, ale prawdopodobnie jest to zły pomysł. W jaki sposób można zagwarantować, że środowisko wykonawcze nie wywoływało funkcji CRT podczas przetwarzania wewnętrznego, które wpłynęło na errno
?
Z tego samego powodu nie należy bezpośrednio dzwonić pod numer GetLastError
. Właściwość DllImportAttribute
zapewnia właściwość SetLastError
, więc środowisko wykonawcze wie, aby natychmiast przechwycić ostatni błąd i zapisać go w miejscu, które kod zarządzany może odczytać, używając Marshal.GetLastWin32Error
.
Myślę, że najbardziej niezawodną rzeczą, jaką można zrobić w tym przypadku, jest utworzenie biblioteki DLL, która wykonuje zarówno rzeczywistą pracę C, jak i przechwytywanie errno
. (Należy pamiętać, że samo zapisanie opakowania wokół przechwytywania errno
nadal będzie miało powyższe obawy.)
Tak, jest to możliwe - GetLastError
robi dokładnie to. Jednakże, jak zauważył binarycoder, nie powinieneś robić tego bezpośrednio - zamiast tego ustaw SetLastError
na swoim DllImport
, aby to zostało wykonane i automatycznie zapisane w pamięci podręcznej (i aby uniknąć problemów z wielowątkowością lub wywołanych w czasie wykonywania funkcji modyfikujących wartość errno
) - wtedy, po wywołaniu Funkcja P/Invoked, sprawdź status powrotu i jeśli pokazuje warunek błędu - wyślij Win32Exception
, który automatycznie odczytuje wartość ostatniego błędu. Tak, nawet w Mono na Linuksie.
Rozwiązaniem jest użycie SetLastError
na DllImport
. Spowoduje to, że środowisko wykonawcze zapisze ostatni błąd, aby można było uzyskać do niego dostęp od Marshal.GetLastWin32Error
.
Istnieją dwa problemy z wywołaniem GetLastError
bezpośrednio:
- Środowisko wykonawcze może zrobić kiedyś po PInvoke powraca przed jesteś w stanie dostać się ostatni błąd
- NET Wiele wątków może znajdować się na tym samym rodzimy wątek. Może to spowodować, że 2 wątki .NET wykonujące PInvokes, natywne biblioteki nie znające żadnej lepszej, będą wtedy nadpisywać ostatni błąd. Wątek A w .NET uzyskuje ostatni błąd wątku B (potencjalnie).
Czy możesz pokazać przykład składni używania 'SetLastError' na' DllImport'? –
- 1. Cel C - zmienna statyczna i globalna?
- 2. Zmienna globalna Klasy Python
- 3. Gdy statyczna zmienna globalna jest tworzona w C++
- 4. Access C++ statyczne metody z C#
- 5. C globalna niezasilana tablica?
- 6. zmienna globalna zawsze zainicjalizowana zero
- 7. zmienna globalna funkcja R
- 8. zmienna globalna "liczyć" niejednoznaczne
- 9. OCaml pusta zmienna globalna
- 10. Jinja2: zmienna lokalna/globalna
- 11. Globalna zmienna i pythonowa kolba
- 12. MySQL "wait_timeout" Zmienna globalna kontra zmienna
- 13. Objective-C Property Access
- 14. TypeScript: Najlepsza globalna statyczna zmienna statyczna
- 15. Nie Funkcja Zmiana zmienna globalna
- 16. Zmienna globalna traci na wartości
- 17. Deklaracja globalna zmienna w coffescript
- 18. Zmienna globalna w pracownikach WWW
- 19. Delphi Dynamic Dll - zmienna globalna
- 20. Python Globalna zmienna nie aktualizowanie
- 21. zmienna globalna dziwactwa w IE
- 22. Gdzie jest zmienna globalna w pliku elfa
- 23. Zmienna globalna w kontrolerze laravel
- 24. Zmienna globalna w Qt, jak?
- 25. Jak zrobić javascript zmienna globalna
- 26. Zmienna abstrakcyjna/właściwość? C#
- 27. Zmienna preprocessor C++
- 28. printf zmienna w C
- 29. Zmienna zakres w C#
- 30. C++ zmienna deklaracji
Tak, zgodziłbym się z tym. Prawdopodobnie lepiej byłoby ustawić wrapper C jako funkcję docelową, która z kolei zwróci wartość errno z tego. – supercheetah