Как я могу сказать, должен ли cbSize быть int или uint в MonitorInfo? - PullRequest
1 голос
/ 13 марта 2012

Я пытаюсь сделать что-то с несколькими мониторами с помощью Platform Invoke. Я использовал http://pinvoke.net, чтобы начать, но столкнулся с проблемой, когда определения не совпадают.

В MONITORINFO (user32) MONITORINFOEX (user32) ), размер определяется как:

public int Size;

Но в EnumDisplayMonitors (user32) , в примере кода, который использует MonitorInfo, мы видим:

mi.size = (uint)Marshal.SizeOf(mi);

Ясно, что одно из них не правильно.

В документах MSDN MONITORINFO объявляется как:

typedef struct tagMONITORINFO {
  DWORD cbSize;
  RECT  rcMonitor;
  RECT  rcWork;
  DWORD dwFlags;
} MONITORINFO, *LPMONITORINFO;

с cbSize определяется как:

Размер структуры, в байтах.

Установите для этого члена значение sizeof (MONITORINFO) перед вызовом функции GetMonitorInfo . Это позволяет функции определить тип структуры, которую вы передаете ей.

Есть идеи, как мне определить, каким оно должно быть, int или uint?

Примечание: я знаю, что некоторые из этих вещей доступны в System.Windows.Forms, но я пытаюсь сделать это, используя P / Invoke в Silverlight 5.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Тип native - DWORD, псевдоним для unsigned int в API Windows.Что имеет смысл, размер структуры никогда не может быть отрицательным.Но объявление pinvoke для такой структуры часто использует int вместо uint .Это делается в объявлении , предоставленном pinvoke.net.

Это часто для удобства, Marshal.SizeOf () возвращает int, а не uint.Это было сделано, чтобы сделать метод CLSCompliant, есть много языков, которые не поддерживают неподписанные типы.Хорошим примером являются Java и оригинальный Visual Basic.

Это не проблема, int и uint имеют одинаковый размер и одинаковый битовый шаблон для значений от 0 до int.MaxValue,Выход за пределы int.MaxValue, чтобы uint имел значение, не является практической проблемой.Структуры никогда не бывают такими большими.И если бы у вас был такой, он все равно был бы непригоден к использованию, CLR не поддерживает управляемые типы размером более 2 ГБ.По крайней мере, до .NET 4.5.

Итак, приступая к ответу на вопрос, фрагмент кода был написан кем-то, кто объявил член структуры как uint, что потребовало приведения.В любом случае это хорошо.

1 голос
/ 13 марта 2012

DWORD - это 32-разрядное целое число без знака, поэтому технически правильное значение uint

. Предполагается, что версия, в которой используется int, была сделана таким образом с помощью легкого лазания.Автор, по-видимому, хотел не приводить возвращаемое значение от Marshal.SizeOf() к uint.

. На практике это просто не имеет значения, поскольку cbSize никогда не достигнет точки, в которой преобразование изподписано без подписи имеет значение.Однако в некоторых случаях это может иметь значение.Например, переменная, которая содержит комбинацию битовых флагов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...