CA1404: Chiamare GetLastError immediatamente dopo P/Invoke
Articolo | Valore |
---|---|
ID regola | CA1404 |
Category | Microsoft.Interoperability |
Modifica | Nessuna interruzione |
Causa
Viene effettuata una chiamata al System.Runtime.InteropServices.Marshal.GetLastWin32Error metodo o alla funzione Win32 GetLastError
equivalente e la chiamata immediatamente precedente a un metodo platform invoke.
Descrizione regola
Un metodo platform invoke accede al codice non gestito e viene definito usando la Declare
parola chiave in Visual Basic o l'attributo System.Runtime.InteropServices.DllImportAttribute . In genere, in caso di errore, le funzioni non gestite chiamano la funzione Win32 SetLastError
per impostare un codice di errore associato all'errore. Il chiamante della funzione non riuscita chiama la funzione Win32 GetLastError
per recuperare il codice di errore e determinare la causa dell'errore. Il codice di errore viene mantenuto per ogni thread e viene sovrascritto dalla chiamata successiva a SetLastError
. Dopo una chiamata a un metodo platform invoke non riuscito, il codice gestito può recuperare il codice di errore chiamando il GetLastWin32Error metodo . Poiché il codice di errore può essere sovrascritto da chiamate interne da altri metodi della libreria di classi gestite, il GetLastError
metodo o GetLastWin32Error deve essere chiamato immediatamente dopo la chiamata al metodo platform invoke.
La regola ignora le chiamate ai membri gestiti seguenti quando si verificano tra la chiamata al metodo platform invoke e la chiamata a GetLastWin32Error. Questi membri non modificano il codice di errore e sono utili per determinare l'esito positivo di alcune chiamate al metodo platform invoke.
Come correggere le violazioni
Per correggere una violazione di questa regola, spostare la chiamata a GetLastWin32Error in modo che segua immediatamente la chiamata al metodo platform invoke.
Quando eliminare gli avvisi
È possibile eliminare un avviso da questa regola se il codice tra la chiamata al metodo platform invoke e la chiamata al GetLastWin32Error metodo non può modificare in modo esplicito o implicito il codice di errore.
Esempio
Nell'esempio seguente viene illustrato un metodo che viola la regola e un metodo che soddisfa la regola.
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace InteroperabilityLibrary
{
internal class NativeMethods
{
private NativeMethods() {}
// Violates rule UseManagedEquivalentsOfWin32Api.
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
internal static extern int ExpandEnvironmentStrings(
string lpSrc, StringBuilder lpDst, int nSize);
}
public class UseNativeMethod
{
string environmentVariable = "%TEMP%";
StringBuilder expandedVariable;
public void ViolateRule()
{
expandedVariable = new StringBuilder(100);
if(NativeMethods.ExpandEnvironmentStrings(
environmentVariable,
expandedVariable,
expandedVariable.Capacity) == 0)
{
// Violates rule CallGetLastErrorImmediatelyAfterPInvoke.
Console.Error.WriteLine(Marshal.GetLastWin32Error());
}
else
{
Console.WriteLine(expandedVariable);
}
}
public void SatisfyRule()
{
expandedVariable = new StringBuilder(100);
if(NativeMethods.ExpandEnvironmentStrings(
environmentVariable,
expandedVariable,
expandedVariable.Capacity) == 0)
{
// Satisfies rule CallGetLastErrorImmediatelyAfterPInvoke.
int lastError = Marshal.GetLastWin32Error();
Console.Error.WriteLine(lastError);
}
else
{
Console.WriteLine(expandedVariable);
}
}
}
}
Regole correlate
CA1060: Spostare P/Invoke nella classe NativeMethods
CA1400: I punti di ingresso P/Invoke devono esistere
CA1401: I P/Invoke non devono essere visibili
CA2101: Specificare il marshalling per argomenti di stringa P/Invoke
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per