CA1404 : Appeler GetLastError immédiatement après P/Invoke
Élément | Valeur |
---|---|
ID de la règle | CA1404 |
Category | Microsoft.Interoperability |
Modification avec rupture | Sans rupture |
Cause
Un appel est effectué à la méthode System.Runtime.InteropServices.Marshal.GetLastWin32Error ou à la fonction Win32 GetLastError
équivalente, et l’appel qui vient immédiatement avant n’est pas à une méthode d’appel de code non managé.
Description de la règle
Une méthode d’appel de code non managé accède au code non managé et est définie à l’aide du mot clé Declare
dans Visual Basic ou de l’attribut System.Runtime.InteropServices.DllImportAttribute. En règle générale, en cas d’échec, les fonctions non managées appellent la fonction Win32 SetLastError
pour définir un code d’erreur associé à l’échec. L’appelant de la fonction ayant échoué appelle la fonction Win32 GetLastError
pour récupérer le code d’erreur et déterminer la cause de l’échec. Le code d’erreur est conservé par thread et est remplacé par l’appel suivant à SetLastError
. Après un appel à une méthode d’appel de code non managé ayant échoué, le code managé peut récupérer le code d’erreur en appelant la méthode GetLastWin32Error. Étant donné que le code d’erreur peut être remplacé par des appels internes à partir d’autres méthodes de bibliothèque de classes managées, la méthode GetLastError
ou GetLastWin32Error doit être appelée immédiatement après l’appel de la méthode d’appel de code non managé.
La règle ignore les appels aux membres managés suivants lorsqu’ils se produisent entre l’appel à la méthode d’appel de code non managé et l’appel à GetLastWin32Error. Ces membres ne modifient pas le code d’erreur et sont utiles pour déterminer la réussite de certains appels de méthode d’appel de code non managé.
Comment corriger les violations
Pour corriger une violation de cette règle, déplacez l’appel à GetLastWin32Error pour qu’il suit immédiatement l’appel à la méthode d’appel de code non managé.
Quand supprimer les avertissements
Il est possible de supprimer un avertissement de cette règle si le code entre l’appel de méthode d’appel de code non managé et l’appel de méthode GetLastWin32Error ne peut pas entraîner explicitement ou implicitement la modification du code d’erreur.
Exemple
L’exemple suivant montre une méthode qui enfreint la règle et une méthode qui est conforme à la règle.
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);
}
}
}
}
Règles associées
CA1060 : Déplacer les P/Invoke vers une classe NativeMethods
CA1400 : Des points d’entrée P/Invoke doivent exister
CA1401 : Les P/Invoke ne doivent pas être visibles
CA2101 : Spécifier le marshaling pour les arguments de chaîne P/Invoke
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour