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