Должен ли dword сопоставляться с int или uint?
при переводе Windows API (включая типы данных) в P/Invoke, я должен заменить DWORD на int
или uint
?
обычно он без знака, но я вижу, что люди используют int
вместо этого везде (это только из-за предупреждения CLS? даже сама .NET Framework тут этой), и поэтому я никогда не уверен, какой из них правильный.
6 ответов
хорошо согласно MSDN DWORD
- целое число без знака с диапазоном от 0 до 4294967295.
поэтому в идеале вы должны заменить его на uint
, а не int
.
однако, как вы заметили uint
не соответствует CLS, поэтому, если ваш метод публично виден, вы должны использовать int
и выполните преобразование. Следствием этого является то, что если ваш метод не используется вне вашей сборки, вы должны отметить его как internal
, а не public
. Тогда вы сможете использовать uint
.
использовать int. Причина в том, если я изменюсь "AutoRestartShell" С uint переменной:
regKey.SetValue("AutoRestartShell", uintVariable);
тип данных в Редактор Реестра изменения "REG_SZ". Если я попрошу, чтобы это значение было возвращено с:
regKey.GetValue("AutoRestartShell");
a строка возвращается.
Если, однако, я изменюсь "AutoRestartShell" С int переменной:
regKey.SetValue("AutoRestartShell", intVariable);
данные тип остается как "параметр DWORD".
почему это происходит? Без понятия. Все, что я знаю, так это то, что он делает. Логика, конечно, сказала бы нам, что uint должен использоваться, но это изменяет тип данных, который мы не хотим.
DWORD по определению (Microsoft) является 32-разрядным целым числом без знака. Он должен сопоставляться с тем типом, который использует компилятор для представления этого.
в наши дни это, скорее всего, unsigned int, но это не портативная реализация. Я знаю, что вы используете C#, но чтобы дать вам пример на языке, с которым я более знаком, типичной реализацией на C может быть:
#if defined(SOME_HARDWARE_IMPLEMENTATION)
#define DWORD unsigned int
#elif #defined(SOME_OTHER_IMPLEMENTATION)
#define DWORD unsigned long
#elif #defined(YET_ANOTHER_IMPLEMENTATION)
#define DWORD something_else
#else
#error Unsupported hardware; cannot map DWORD
#endif
предупреждение о соответствии CLS применяется, только если метод P / Invoke виден вне сборки, что обычно означает, что вызов является открытым. Если метод не виден извне, то допустимо использовать uint
.
к сожалению, Read Registry должен использовать int в противном случае исключение throw.это Майкрософт код:
private static void Get45or451FromRegistry()
{
using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\")) {
if (ndpKey != null && ndpKey.GetValue("Release") != null) {
Console.WriteLine("Version: " + CheckFor45DotVersion((int) ndpKey.GetValue("Release")));
}
else {
Console.WriteLine("Version 4.5 or later is not detected.");
}
}
}
хотя выпуск REG_DWORD