Freigeben über


FindFile-Beispiel

Dieses Beispiel demonstriert die Übergabe einer Struktur, die eine weitere, eingebettete Struktur enthält, an eine nicht verwaltete Funktion. Darüber hinaus demonstriert es die Verwendung des MarshalAsAttribute-Attributs zum Deklarieren eines Arrays mit fester Länge innerhalb der Struktur. In diesem Beispiel werden die Elemente der eingebetteten Struktur der übergeordneten Struktur hinzugefügt. Ein Beispiel für eine nicht vereinfachte eingebettete Struktur finden Sie unter Beispiel für Strukturen.

Das FindFile-Beispiel verwendet die folgende nicht verwaltete Funktion, die zusammen mit ihrer ursprünglichen Funktionsdeklaration aufgeführt wird:

  • FindFirstFile aus Kernel32.dll exportiert.

    HANDLE FindFirstFile(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData);
    

Die ursprüngliche, an die Funktion übergebene Struktur enthält die folgenden Elemente:

typedef struct _WIN32_FIND_DATA 
{
  DWORD    dwFileAttributes; 
  FILETIME ftCreationTime; 
  FILETIME ftLastAccessTime; 
  FILETIME ftLastWriteTime; 
  DWORD    nFileSizeHigh; 
  DWORD    nFileSizeLow; 
  DWORD    dwReserved0; 
  DWORD    dwReserved1; 
  TCHAR    cFileName[ MAX_PATH ]; 
  TCHAR    cAlternateFileName[ 14 ]; 
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

In diesem Beispiel enthält die FindData-Klasse für jedes Element der Originalstruktur und der eingebetteten Struktur einen entsprechenden Datenmember. Anstelle zweier ursprünglicher Zeichenpuffer ersetzt die Klasse Zeichenfolgen. MarshalAsAttribute legt die UnmanagedType-Enumeration auf ByValTStr fest. Dieser Wert wird zum Identifizieren der Inlinearrays fester Länge verwendet, die innerhalb der nicht verwalteten Strukturen erscheinen.

Die LibWrap-Klasse enthält einen verwalteten Prototyp der FindFirstFile-Methode, der die FindData-Klasse als Parameter übergibt. Der Parameter muss mit dem InAttribute-Attribut und dem OutAttribute-Attribut deklariert werden, da Klassen, bei denen es sich um Referenztypen handelt, standardmäßig als In-Parameter übergeben werden.

Deklarieren von Prototypen

' Declares a class member for each structure element.
< StructLayout(LayoutKind.Sequential, CharSet := CharSet.Auto)> _
Public Class FindData
    Public fileAttributes As Integer = 0
    ' creationTime was a by-value FILETIME structure.
    Public creationTime_lowDateTime As Integer = 0
    Public creationTime_highDateTime As Integer = 0
    ' lastAccessTime was a by-value FILETIME structure.
    Public lastAccessTime_lowDateTime As Integer = 0
    Public lastAccessTime_highDateTime As Integer = 0
    ' lastWriteTime was a by-value FILETIME structure.
    Public lastWriteTime_lowDateTime As Integer = 0
    Public lastWriteTime_highDateTime As Integer = 0
    Public nFileSizeHigh As Integer = 0
    Public nFileSizeLow As Integer = 0
    Public dwReserved0 As Integer = 0
    Public dwReserved1 As Integer = 0
    < MarshalAs(UnmanagedType.ByValTStr, SizeConst := 260)> _
    Public fileName As String = Nothing
    < MarshalAs(UnmanagedType.ByValTStr, SizeConst := 14)> _
    Public alternateFileName As String = Nothing
End Class 'FindData

Public Class LibWrap
   ' Declares a managed prototype for the unmanaged function.
   Declare Auto Function FindFirstFile Lib "Kernel32.dll" _
      (ByVal fileName As String, <[In], Out> ByVal findFileData As _
      FindData) As IntPtr
End Class
// Declares a class member for each structure element.
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
public class FindData
{
    public int  fileAttributes = 0;
    // creationTime was an embedded FILETIME structure.
    public int  creationTime_lowDateTime = 0 ;
    public int  creationTime_highDateTime = 0;
    // lastAccessTime was an embedded FILETIME structure.
    public int  lastAccessTime_lowDateTime = 0;
    public int  lastAccessTime_highDateTime = 0;
    // lastWriteTime was an embedded FILETIME structure.
    public int  lastWriteTime_lowDateTime = 0;
    public int  lastWriteTime_highDateTime = 0;
    public int  nFileSizeHigh = 0;
    public int  nFileSizeLow = 0;
    public int  dwReserved0 = 0;
    public int  dwReserved1 = 0;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
    public String  fileName = null;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)]
    public String  alternateFileName = null;
}

public class LibWrap
{
    // Declares a managed prototype for the unmanaged function.
    [DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
    public static extern IntPtr FindFirstFile(string fileName, [In, Out]
        FindData findFileData);
}
// Declares a class member for each structure element.
[StructLayout(LayoutKind::Sequential, CharSet=CharSet::Auto)]
public ref class FindData
{
public:
    int  fileAttributes;
    // creationTime was an embedded FILETIME structure.
    int  creationTime_lowDateTime;
    int  creationTime_highDateTime;
    // lastAccessTime was an embedded FILETIME structure.
    int  lastAccessTime_lowDateTime;
    int  lastAccessTime_highDateTime;
    // lastWriteTime was an embedded FILETIME structure.
    int  lastWriteTime_lowDateTime;
    int  lastWriteTime_highDateTime;
    int  nFileSizeHigh;
    int  nFileSizeLow;
    int  dwReserved0;
    int  dwReserved1;
    [MarshalAs(UnmanagedType::ByValTStr, SizeConst=260)]
    String^  fileName;
    [MarshalAs(UnmanagedType::ByValTStr, SizeConst=14)]
    String^  alternateFileName;
};

public ref class LibWrap
{
public:
    // Declares a managed prototype for the unmanaged function.
    [DllImport("Kernel32.dll", CharSet=CharSet::Auto)]
    static IntPtr FindFirstFile(String^ fileName, [In, Out]
        FindData^ findFileData);
};

Aufrufen von Funktionen

Public Class App
    Public Shared Sub Main()
        Dim fd As New FindData()
        Dim handle As IntPtr = LibWrap.FindFirstFile("C:\*.*", fd)
        Console.WriteLine("The first file: {0}", fd.fileName)
    End Sub
End Class
public class App
{
    public static void Main()
    {
        FindData fd = new FindData();
        IntPtr handle = LibWrap.FindFirstFile("C:\\*.*", fd);
        Console.WriteLine("The first file: {0}", fd.fileName);
    }
}
public ref class App
{
public:
    static void Main()
    {
        FindData^ fd = gcnew FindData();
        IntPtr handle = LibWrap::FindFirstFile("C:\\*.*", fd);
        Console::WriteLine("The first file: {0}", fd->fileName);
    }
};

Siehe auch

Konzepte

Marshallen von Klassen, Strukturen und Unions

Datentypen für den Plattformaufruf

Erstellen von Prototypen in verwaltetem Code