FindFile 範例
這個範例示範如何傳遞結構,其包含 Unmanaged 函式的第二個內嵌結構。它也示範如何使用 MarshalAsAttribute 屬性來宣告結構內固定長度的陣列。在這個範例中,內嵌結構元素會被加入父結構。如需未簡維的內嵌結構範例,請參閱結構範例。
FindFile 範例使用下列 Unmanaged 函式,顯示其原始函式宣告:
從 Kernel32.dll 匯出 FindFirstFile。
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,用來識別出現在 Unmanaged 結構之中的內嵌、固定長度的字元陣列。
LibWrap
類別包含 FindFirstFile
方法的 Managed 原型,會將 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 );
}
}