CA2205: Utilizzare equivalenti gestiti dell'API Win32
TypeName |
UseManagedEquivalentsOfWin32Api |
CheckId |
CA2205 |
Category |
Microsoft.Usage |
Breaking Change |
Non sostanziale |
Causa
Viene definito un metodo di platform invoke e nella libreria di classi .NET Framework è presente un metodo con la funzionalità equivalente.
Descrizione della regola
Un metodo di platform invoke 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 platform invoke 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 platform invoke può inoltre causare ulteriori problemi di sicurezza che dovranno essere risolti.
Come correggere le 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 platform invoke che viola la regola.Vengono inoltre illustrate le chiamate al metodo di platform invoke 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
CA1404: Chiamare GetLastError immediatamente dopo P/Invoke
CA1060: Spostare i 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 gli argomenti di stringa P/Invoke