Должен ли 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.


он без знака, поэтому сопоставьте его с 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