如何判断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的人写的,因此需要演员。无论哪种方式都很好。