CA2205: Verwaltete Entsprechungen der Win32 API verwenden
TypeName |
UseManagedEquivalentsOfWin32Api |
CheckId |
CA2205 |
Kategorie |
Microsoft.Usage |
Unterbrechende Änderung |
Nicht unterbrechend |
Ursache
Eine Plattformaufrufmethode ist definiert, und in der .NET Framework-Klassenbibliothek existiert eine Methode mit der entsprechenden Funktionalität.
Regelbeschreibung
Mit einer Plattformaufrufmethode wird eine nicht verwaltete DLL-Funktion aufgerufen. Die Aufrufmethode wird mit dem System.Runtime.InteropServices.DllImportAttribute-Attribut bzw. in Visual Basic mit dem Declare-Schlüsselwort definiert. Eine fehlerhaft definierte Plattformaufrufmethode kann zu Laufzeitausnahmen führen. Mögliche Gründe hierfür sind Probleme wie falsch benannte Funktionen, eine fehlerhafte Zuordnung von Datentypen für Parameter und Rückgabewerte sowie fehlerhafte Feldspezifikationen, beispielsweise eine falsche Aufrufkonvention und ein falscher Zeichensatz. Falls die entsprechende verwaltete Methode verfügbar ist, ist ein Aufruf dieser Methode im Allgemeinen einfacher und weniger fehleranfällig als eine Definition oder ein direkter Aufruf der nicht verwalteten Methode. Der Aufruf einer Plattformaufrufmethode kann außerdem zu zusätzlichen Sicherheitsproblemen führen, die behandelt werden müssen.
Behandeln von Verstößen
Um einen Verstoß gegen diese Regel zu beheben, ersetzen Sie den Aufruf der nicht verwalteten Funktion durch einen Aufruf der entsprechenden verwalteten Funktion.
Wann sollten Warnungen unterdrückt werden?
Unterdrücken Sie eine Warnung dieser Regel, wenn die benötigte Funktionalität durch die vorgeschlagene Ersetzungsmethode nicht bereitgestellt wird.
Beispiel
Im folgenden Beispiel wird eine Plattformaufrufmethodendefinition veranschaulicht, die gegen die Regel verstößt. Darüber hinaus werden die Aufrufe der Plattformaufrufmethode und der entsprechenden verwalteten Methode dargestellt.
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);
}
}
}
Verwandte Regeln
CA1404: GetLastError unmittelbar nach P/Invoke aufrufen
CA1060: P/Invokes in NativeMethods-Klasse verschieben
CA1400: Für P/Invoke müssen Einstiegspunkte vorhanden sein
CA1401: P/Invokes dürfen nicht sichtbar sein
CA2101: Marshalling für P/Invoke-Zeichenfolgenargumente festlegen