如何判断cbSize是否应该在MonitorInfo中为int或uint?
我想使用平台调用来做一些多显示器的东西。我一直在使用http://pinvoke.net来启动我,但我遇到了定义不一致的问题。如何判断cbSize是否应该在MonitorInfo中为int或uint?
在MONITORINFO (user32)(和MONITORINFOEX (user32)),大小被定义为:
public int Size;
但在EnumDisplayMonitors (user32),在使用monitorInfo的示例代码,我们看到:
mi.size = (uint)Marshal.SizeOf(mi);
显然,一个的这些是不正确的。
typedef struct tagMONITORINFO {
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
} MONITORINFO, *LPMONITORINFO;
与CBSIZE定义为::
该结构的大小,以字节
在MSDN文档,如MONITORINFO被声明。
在调用GetMonitorInfo函数之前,将此成员设置为sizeof(MONITORINFO)。这样做可以让函数确定传递给它的结构的类型。
任何想法如何能解决它应该是,int或uint?
注:我知道一些这方面的东西是System.Windows.Forms的可用,但我试图做到这一点使用P/Invoke在Silverlight 5
DWORD
是一个32位无符号整数,因此uint
在技术上是正确的。
使用int
的版本大概是通过温和的懒散来完成的。作者可能不希望将Marshal.SizeOf()
的返回值转换为uint
。
在实践中,这里根本没有关系,因为cbSize
永远不会达到从signed到unsigned的转换有任何区别的地步。但是,在某些情况下,它可能很重要。例如,一个保存位标志组合的变量。
本地类型是DWORD,它是Windows API中unsigned int的别名。这是有道理的,结构的大小永远不会是负面的。但是这种结构的pinvoke声明通常使用int而不是uint。它在pinvoke.net提供的declaration中。
这通常是为了方便,Marshal.SizeOf()返回一个int,而不是一个uint。这样做是为了使方法CLSCompliant,有许多语言不支持无符号类型。 Java和原始的Visual Basic就是很好的例子。
这是不是一个问题,一个int和一个uint具有相同的大小和相同的位模式为0和int.MaxValue之间的值。超越int.MaxValue以使uint重要不是一个实际问题。结构从来没有那么大。如果你有一个,它将无法使用,CLR不支持大于2GB的托管类型。至少到.NET 4.5。
因此,要回答这个问题,代码片段是由声明结构成员为uint的人写的,因此需要演员。无论哪种方式都很好。