2012-03-13 299 views
1

我想使用平臺調用來做一些多顯示器的東西。我一直在使用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

回答

1

DWORD是一個32位無符號整數,因此uint在技​​術上是正確的。

使用int的版本大概是通過溫和的懶散來完成的。作者可能不希望將Marshal.SizeOf()的返回值轉換爲uint

在實踐中,這裏根本沒有關係,因爲cbSize永遠不會達到從signed到unsigned的轉換有任何區別的地步。但是,在某些情況下,它可能很重要。例如,一個保存位標誌組合的變量。

1

本地類型是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的人寫的,因此需要演員。無論哪種方式都很好。

相關問題