扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:hahahawk 来源:天极论坛 2007年11月14日
关键字:
[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)] public class MySystemTime { [FieldOffset(0)]public ushort wYear; [FieldOffset(2)]public ushort wMonth; [FieldOffset(4)]public ushort wDayOfWeek; [FieldOffset(6)]public ushort wDay; [FieldOffset(8)]public ushort wHour; [FieldOffset(10)]public ushort wMinute; [FieldOffset(12)]public ushort wSecond; [FieldOffset(14)]public ushort wMilliseconds; } |
下面是针对API中OSVERSIONINFO结构,在.net中定义对应类或结构的例子:
/********************************************** //.net中声明为类 [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )] [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )] |
此例中用到MashalAs特性,它用于描述字段、方法或参数的封送处理格式。用它作为参数前缀并指定目标需要的数据类型。例如,以下代码将两个参数作为数据类型长指针封送给 Windows API 函数的字符串 (LPStr):
[MarshalAs(UnmanagedType.LPStr)] String existingfile; [MarshalAs(UnmanagedType.LPStr)] String newfile; |
注意结构作为参数时候,一般前面要加上ref修饰符,否则会出现错误:对象的引用没有指定对象的实例。
[ DllImport( "kernel32", EntryPoint="GetVersionEx" )] public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi ); |
三、如何保证使用托管对象的平台调用成功?
如果在调用平台 invoke 后的任何位置都未引用托管对象,则垃圾回收器可能将完成该托管对象。这将释放资源并使句柄无效,从而导致平台invoke 调用失败。用 HandleRef 包装句柄可保证在平台 invoke 调用完成前,不对托管对象进行垃圾回收。
例如下面:
FileStream fs = new FileStream( "a.txt", FileMode.Open ); StringBuilder buffer = new StringBuilder( 5 ); int read = 0; ReadFile(fs.Handle, buffer, 5, out read, 0 ); //调用Win API中的ReadFile函数 |
由于fs是托管对象,所以有可能在平台调用还未完成时候被垃圾回收站回收。将文件流的句柄用HandleRef包装后,就能避免被垃圾站回收:
[ DllImport( "Kernel32.dll" )] |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者