Поделиться через


Пример FindFile

Обновлен: Ноябрь 2007

В этом примере показан способ передачи структуры, содержащей вторую, внедренную структуру, в неуправляемую функции. Также показан способ использования атрибута MarshalAsAttribute для объявления массива фиксированной длины внутри структуры. В этом примере внедренные элементы структуры добавляются в родительскую структуру. Пример внедренной структуры (не выровненной) см. в разделе Пример структур.

В примере FindFile используются следующие неуправляемые функции (показано их исходное объявление).

  • Функция FindFirstFile, экспортированная из Kernel32.dll.

    HANDLE FindFirstFile(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData);
    

Исходная структура, переданная функции, содержит следующие элементы:

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;

В этом примере класс FindData содержит члены данных, соответствующие каждому элементу исходной и внедренной структур. Вместо двух исходных символьных буферов класс подставляет строки. Атрибут MarshalAsAttribute устанавливает перечисление UnmanagedType равным значению ByValTStr, которое используется для идентификации встроенных символьных массивов фиксированной длины внутри неуправляемых структур.

Класс LibWrap содержит управляемый прототип метода FindFirstFile, передающий класс FindData в качестве параметра. Этот параметр должен быть объявлен с атрибутами InAttribute и OutAttribute, так как классы, являющиеся ссылочными типами, по умолчанию передаются как параметры In.

Исходный код для следующих примеров кода см. в разделе Пример технологии вызова неуправляемого кода для .NET Framework.

Объявление прототипов

' 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 := 256 )> _
   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 'LibWrap
// Declares a class member for 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=256 )]
   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 );
}

Вызов функций

Public Class App
   Public Shared Sub Main()
   
      Dim fd As New FindData()
      LibWrap.FindFirstFile( "C:\*", fd )
      Console.WriteLine( "The first file: {0}", fd.fileName )
      
   End Sub 'Main
End Class 'App
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 );
   }
}

См. также

Основные понятия

Маршалинг классов, структур и объединений

Типы данных вызовов неуправляемого кода

Создание прототипов в управляемом коде