È possibile accedere alla variabile "errno" in C# quando P/Invocazione? Questo è simile a Win32 GetLastError().Variabile globale di accesso C 'errno' da C#
risposta
Sono abbastanza sicuro che ci sia un modo, ma probabilmente è una cattiva idea. Come garantiresti che il runtime non abbia richiamato alcuna funzione CRT durante l'elaborazione interna che ha interessato lo errno
?
Per lo stesso motivo, non chiamare direttamente GetLastError
. Il DllImportAttribute
fornisce una proprietà SetLastError
in modo che il runtime sappia immediatamente catturare l'ultimo errore e memorizzarlo in una posizione che il codice gestito può leggere utilizzando Marshal.GetLastWin32Error
.
Penso che la cosa più efficace che si possa fare in questo caso sia creare una DLL C che esegua sia l'effettivo lavoro C che l'acquisizione dello errno
. (Si noti che la sola scrittura di un wrapper attorno all'acquisizione errno
avrebbe ancora le preoccupazioni sopra menzionate.)
Sì, è possibile - GetLastError
fa esattamente questo. Tuttavia, come indicato da binarycoder, non dovresti farlo direttamente - invece, imposta SetLastError
sul tuo DllImport
affinché questo venga eseguito e memorizzato nella cache automaticamente (e per evitare problemi di multithreading o funzioni richiamate dal runtime che modificano il valore errno
), quindi, invocando il P/Funzione richiamata, controlla lo stato di ritorno e se mostra una condizione di errore - lancia Win32Exception
, che legge automaticamente il valore dell'ultimo errore. Sì, anche su Mono su Linux.
La soluzione è utilizzare SetLastError
su DllImport
. Ciò farà sì che il runtime salvi l'ultimo errore, quindi è possibile accedervi da Marshal.GetLastWin32Error
.
Ci sono due problemi con chiamando direttamente GetLastError
:
- Il runtime potrebbe fare qualche tempo dopo la PInvoke torna prima di essere in grado di ottenere l'ultimo errore
- multi-thread .NET possono risiedere sullo stesso nativo filo. Ciò può causare 2 thread .NET che eseguono PInvokes, le librerie native che non lo conoscono meglio, quindi sovrascrivono l'ultimo errore. Quindi, il thread A in .NET riceve l'ultimo errore del thread B (potenzialmente).
Puoi mostrare un esempio della sintassi per l'uso di 'SetLastError' su' DllImport'? –
- 1. Impostazione della variabile LUA_PATH globale da C++/C?
- 2. Accesso alla variabile globale da AngularJS
- 3. C/C++ globale vs statico globale
- 4. Accesso variabile globale a Swift
- 5. Obiettivo C - Variabile statica e globale?
- 6. Variabile globale condivisa nella libreria statica C++
- 7. accesso variabile simultaneo in c
- 8. variabile globale V.S. variabile di file in C++
- 9. Accesso a una variabile globale da qualsiasi controller di app
- 10. Accesso variabile globale dall'interno di una classe
- 11. Variabile globale di accesso PHP in funzione
- 12. Accesso al namespace globale C++ dall'interno di un altro namespace
- 13. Accesso a una variabile da un altro script C#
- 14. extern con definizione globale di variabile in c
- 15. PowerShell - Ottieni variabile da C# Cmdlet
- 16. Accesso globale in Java
- 17. implementazione variabile globale
- 18. Accesso XAML controlla da C# code-behind
- 19. Variabile statica C++
- 20. Quando la variabile globale statica viene creata in C++
- 21. C la stessa variabile globale definita in diversi file
- 22. C forcella che fare con la variabile globale
- 23. Java globale namespace accesso
- 24. Imposta la variabile di ambiente globale da Node.js
- 25. Mocking una variabile globale
- 26. Accesso globale vs. variabili locali
- 27. accesso casuale CSV; C#
- 28. Nessuna inizializzazione globale variabile
- 29. Come faccio a utilizzare errno in C++
- 30. Accesso a Swift Extension da Objective-C
Sì, sarei d'accordo. Probabilmente sarebbe meglio impostare un wrapper C come una funzione target che restituirebbe a sua volta il valore di errno. – supercheetah