Подтвердить что ты не робот

Должна ли DWORD сопоставлять int или uint?

При переводе API Windows (включая типы данных) в P/Invoke следует заменить DWORD на int или uint?

Обычно он без знака, но я вижу людей, использующих int везде (это просто из-за предупреждения CLS? даже сама .NET Framework делает this), и поэтому я никогда не уверен, какой из них правильный.

4b9b3361

Ответ 1

Ну в соответствии с MSDN DWORD - целое число без знака с диапазоном от 0 до 4294967295.

В идеале вы должны заменить его uint, а не int.

Однако, поскольку вы заметили, что uint не соответствует CLS, поэтому, если ваш метод является общедоступным, вы должны использовать int и выполнить преобразование. Следствием этого является то, что если ваш метод не используется вне вашей сборки, вы должны пометить его как internal, а не public. Тогда вы сможете использовать uint.

Ответ 2

Без знака, сопоставьте его с uint.

Ответ 3

Использовать int. Причина в том, что если я изменяю "AutoRestartShell" с переменной uint:

regKey.SetValue("AutoRestartShell", uintVariable);

тип данных в Редакторе реестра изменяется на "REG_SZ" . Если я попрошу вернуть это значение с помощью:

regKey.GetValue("AutoRestartShell");

возвращается строка.

Если, однако, я изменяю "AutoRestartShell" с переменной int:

regKey.SetValue("AutoRestartShell", intVariable);

Тип данных остается "REG_DWORD" .

Почему это происходит? Без понятия. Все, что я знаю, это так. Логика наверняка сообщит нам, что uint следует использовать, но это меняет тип данных, который нам не нужен.

Ответ 4

DWORD по определению (Microsoft) представляет собой 32-битовое целое без знака. Он должен сопоставляться с тем типом, который ваш компилятор использует для представления.

В наши дни это, скорее всего, unsigned int, но это не переносная реализация. Я знаю, что вы используете С#, но чтобы дать вам пример на языке, с которым я больше знаком, типичная реализация на 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

Ответ 5

Предупреждение о соответствии CLS применяется только в том случае, если метод P/Invoke отображается вне сборки, что обычно означает, что вызов является общедоступным. Если метод внешне не виден, допустимо использовать uint.

Ответ 6

К сожалению, чтение реестра должно использовать int, иначе бросать exception.this код Microsoft:

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