Partager via


CA2205 : Utilisez des équivalents managés de l'API Win32

TypeName

UseManagedEquivalentsOfWin32Api

CheckId

CA2205

Catégorie

Microsoft.Usage

Modification avec rupture

Modification sans rupture

Cause

Une méthode d'appel de code non managé est définie et une méthode dotée de la fonctionnalité équivalente existe dans la bibliothèque de classes du .NET Framework.

Description de la règle

Une méthode d'appel de code non managé est utilisée pour appeler une fonction DLL non managée et est définie à l'aide de l'attribut System.Runtime.InteropServices.DllImportAttribute, ou du mot clé Declare en Visual Basic. Une méthode d'appel de code non managé incorrectement définie peut engendrer des exceptions au moment de l'exécution du fait de problèmes tels qu'une fonction incorrectement nommée, un mappage erroné de types de données de valeurs de retour et de paramètres, et des spécifications de champs inexactes, notamment en termes de convention d'appel et de jeu de caractères. Autant que faire se peut, appeler la méthode managée équivalente est généralement plus simple et moins propice aux erreurs que définir et appeler la méthode non managée directement. L'appel à une méthode d'appel de code non managé peut également engendrer des problèmes de sécurité supplémentaires qui doivent être résolus.

Comment corriger les violations

Pour corriger une violation de cette règle, remplacez l'appel à la fonction non managée par un appel à son équivalent managé.

Quand supprimer les avertissements

Supprimez un avertissement de cette règle si la méthode de remplacement suggérée ne fournit pas les fonctionnalités nécessaires.

Exemple

L'exemple suivant présente une définition de méthode d'appel de code non managé qui enfreint la règle. Sont également présentés les appels à la méthode d'appel de code non managé ainsi que la méthode managée équivalente.

Imports System
Imports System.Runtime.InteropServices
Imports System.Text

Namespace UsageLibrary

   Class NativeMethods

      Private Sub New()
      End Sub

      ' The following method definitions violate the rule.

      <DllImport("kernel32.dll", CharSet := CharSet.Unicode, _ 
         SetLastError := True)> _ 
      Friend Shared Function ExpandEnvironmentStrings _ 
         (lpSrc As String, lpDst As StringBuilder, nSize As Integer) _ 
         As Integer
      End Function

      Friend Declare Unicode Function ExpandEnvironmentStrings2 _ 
         Lib "kernel32.dll" Alias "ExpandEnvironmentStrings" _ 
         (lpSrc As String, lpDst As StringBuilder, nSize As Integer) _ 
         As Integer

   End Class

   Public Class UseNativeMethod

      Shared Sub Main()

         Dim environmentVariable As String = "%TEMP%"
         Dim expandedVariable As New StringBuilder(100)

         ' Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings( _ 
            environmentVariable, _ 
            expandedVariable, _ 
            expandedVariable.Capacity)

         ' Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings2( _ 
            environmentVariable, _ 
            expandedVariable, _ 
            expandedVariable.Capacity)

         ' Call the equivalent managed method.
         Environment.ExpandEnvironmentVariables(environmentVariable)

      End Sub

   End Class

End Namespace
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace UsageLibrary
{
   internal class NativeMethods
   {
      private NativeMethods() {}

      // The following method definition violates the rule.
      [DllImport("kernel32.dll", CharSet = CharSet.Unicode, 
          SetLastError = true)]
      internal static extern int ExpandEnvironmentStrings(
         string lpSrc, StringBuilder lpDst, int nSize);
   }

   public class UseNativeMethod
   {
      public void Test()
      {
         string environmentVariable = "%TEMP%";
         StringBuilder expandedVariable = new StringBuilder(100);

         // Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings(
            environmentVariable, 
            expandedVariable, 
            expandedVariable.Capacity);

         // Call the equivalent managed method.
         Environment.ExpandEnvironmentVariables(environmentVariable);
      }
   }
}

Règles connexes

CA1404 : Appeler GetLastError immédiatement après P/Invoke

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écifiez le marshaling pour les arguments de chaîne P/Invoke