Condividi tramite


Utilizzare equivalenti gestiti dell'API Win32

Aggiornamento: novembre 2007

TypeName

UseManagedEquivalentsOfWin32Api

CheckId

CA2205

Category

Microsoft.Usage

Breaking Change

Non sostanziale

Causa

Viene definito un metodo di richiamo piattaforma e nella libreria di classi .NET Framework è presente un metodo con la funzionalità equivalente.

Descrizione della regola

Un metodo di richiamo piattaforma viene utilizzato per chiamare una funzione DLL non gestita e viene definito mediante l'attributo System.Runtime.InteropServices.DllImportAttribute o la parola chiave Declare in Visual Basic. Un metodo di richiamo piattaforma definito in modo errato può causare eccezioni in fase di esecuzione come conseguenza di problemi quali funzione con nome non corretto, mapping errato dei tipi di dati di parametri e valori restituiti oppure specifiche di campi errate, ad esempio la convenzione di chiamata e il set di caratteri. Se disponibile, è in genere più semplice e presenta minori possibilità di errore chiamare il metodo gestito equivalente anziché definire e chiamare direttamente il metodo non gestito. La chiamata a un metodo di richiamo piattaforma può inoltre causare ulteriori problemi di protezione che dovranno essere risolti.

Correzione di violazioni

Per correggere una violazione di questa regola, sostituire la chiamata alla funzione non gestita con una chiamata al relativo equivalente gestito.

Esclusione di avvisi

Escludere un avviso da questa regola se il metodo di sostituzione consigliato non fornisce la funzionalità desiderata.

Esempio

Nell'esempio riportato di seguito viene illustrata una definizione di metodo di richiamo piattaforma che viola la regola. Vengono inoltre illustrate le chiamate al metodo di richiamo piattaforma e al metodo gestito equivalente.

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);
      }
   }
}

Regole correlate

Chiamare GetLastError immediatamente dopo P/Invoke

Spostare i P/Invoke nella classe dei metodi nativi

I punti di ingresso P/Invoke devono esistere

I P/Invokes non devono essere visibili

Specificare il marshalling per gli argomenti di stringa P/Invoke