用法示例:
Capability capability;if (UnsafeNativeMethods.Ioctl(handle, request, ref capability) == -1){ throw new UnixIOException();}能力:
[StructLayout(LayoutKind.Sequential, Size = 104)]internal struct Capability{ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string Driver; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string Device; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string BusInfo; public uint Version; public CapabilityFlags Capabilities;}UnsafeNativeMethods:
internal static class UnsafeNativeMethods{ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [Dllimport("libc", EntryPoint = "close", SetLastError = true)] internal static extern int Close(IntPtr handle); [Dllimport("libc", EntryPoint = "ioctl", SetLastError = true)] internal static extern int Ioctl(SafeUnixHandle handle, uint request, ref Capability capability); [Dllimport("libc", EntryPoint = "open", SetLastError = true)] internal static extern SafeUnixHandle Open(string path, uint flag, int mode); internal static string Strerror(int error) { try { var buffer = new StringBuilder(256); var result = Strerror(error, buffer, (ulong)buffer.Capacity); return (result != -1) ? buffer.ToString() : null; } catch (EntryPointNotFoundException) { return null; } } [Dllimport("MonoPosixHelper", EntryPoint = "Mono_Posix_Syscall_strerror_r", SetLastError = true)] private static extern int Strerror(int error, [Out] StringBuilder buffer, ulong length);}SafeUnixHandle:
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)][SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]internal sealed class SafeUnixHandle : SafeHandle{ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private SafeUnixHandle() : base(new IntPtr(-1), true) { } public override bool IsInvalid { get { return this.handle == new IntPtr(-1); } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { return UnsafeNativeMethods.Close(this.handle) != -1; }}UnixIOException:
[Serializable]public class UnixIOException : ExternalException{ private readonly int nativeErrorCode; [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public UnixIOException() : this(Marshal.GetLastWin32Error()) { } [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public UnixIOException(int error) : this(error, GetErrorMessage(error)) { } [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] public UnixIOException(string message) : this(Marshal.GetLastWin32Error(), message) { } public UnixIOException(int error, string message) : base(message) { this.nativeErrorCode = error; } public UnixIOException(string message, Exception innerException) : base(message, innerException) { } protected UnixIOException(SerializationInfo info, StreamingContext context) : base(info, context) { this.nativeErrorCode = info.GetInt32("NativeErrorCode"); } public int NativeErrorCode { get { return this.nativeErrorCode; } } public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } info.AddValue("NativeErrorCode", this.nativeErrorCode); base.GetObjectData(info, context); } private static string GetErrorMessage(int error) { var errorDescription = UnsafeNativeMethods.Strerror(error); return errorDescription ?? string.Format("Unknown error (0x{0:x})", error); }}


