标签:
在上一篇 c# 如何调用非托管函数 中介绍了调用非托管函数的简单方法,其中传递的都是简单的值类型,如uint等。本篇将介绍如何传递结构或类到非托管函数。
以系统函数 GetSystemTime 为例,以下分别演示了如何传递结构和类。
一 传递结构
参考MSDN可以知道他的定义为:
void WINAPI GetSystemTime(__out LPSYSTEMTIME lpSystemTime);
其中LPSYSTEMTIME 就是一个结构体:
typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, *PSYSTEMTIME;
根据原始定义我们可以把它转成C#的形式(word类型相当于c#中的ushort)
[StructLayout(LayoutKind.Sequential)] public struct SystemTime { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; }
由于该结构是作为out参数传递的,因此在c#中我们必须通过引用来传递:
[DllImport("Kernel32.dll")] public static extern void GetSystemTime(ref SystemTime st);
以下是完整代码:
public class Kernel32 { [StructLayout(LayoutKind.Sequential)] public struct SystemTime { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; }
[DllImport("Kernel32.dll")] public static extern void GetSystemTime(ref SystemTime st); }
调用起来也比较简单:
private void btnGetSysTime_Click(object sender, EventArgs e) { Kernel32.SystemTime sysTime = new Kernel32.SystemTime(); Kernel32.GetSystemTime(ref sysTime);
MessageBox.Show(string.Format("{0}-{1}-{2} {3}:{4}:{5}", sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, sysTime.wSecond)); }
二 传递类
对于以上的例子,我们也可以把结构改成类传递给非托管函数,因为类是引用类型,所以我们不再需要ref声明:
public class Kernel32 { [StructLayout(LayoutKind.Sequential)] public class SystemTime { public ushort wYear; public ushort wMonth; public ushort wDayOfWeek; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort wMilliseconds; }
[DllImport("Kernel32.dll")] public static extern void GetSystemTime(SystemTime st); }
注意这里只是一个特例,并不是所有的情况既可以定义成结构类型也可以定义成类类型,通常我们应遵循以下原则:
参考:
标签:
原文地址:http://www.cnblogs.com/shanfeng/p/4394651.html