Should DWORD map to int or uint?

2020-05-29 17:00发布

When translating the Windows API (including data types) into P/Invoke, should I replace DWORD with int or uint?

It's normally unsigned, but I see people using int everywhere instead (is it just because of the CLS warning? even the .NET Framework itself does this), and so I'm never really sure which one is the correct one to use.

7条回答
ゆ 、 Hurt°
2楼-- · 2020-05-29 17:09

Use int. Reason being, if I change "AutoRestartShell" with a uint variable:

regKey.SetValue("AutoRestartShell", uintVariable);

the data type in the Registry Editor changes to "REG_SZ". If I ask for that value to be returned with:

regKey.GetValue("AutoRestartShell");

a string gets returned.

If, however, I change "AutoRestartShell" with an int variable:

regKey.SetValue("AutoRestartShell", intVariable);

The data type stays as "REG_DWORD".

Why does this happen? No idea. All I know is that it does. Logic certainly would tell us that uint should be used but that changes the data type which we don't want.

查看更多
Rolldiameter
3楼-- · 2020-05-29 17:15

The CLS compliance warning applies only if the P/Invoke method is visible outside the assembly, which generally means the call is public. If the method is not externally visible, then it is acceptable to use uint.

查看更多
Ridiculous、
4楼-- · 2020-05-29 17:20

It's unsigned so map it to uint.

查看更多
甜甜的少女心
5楼-- · 2020-05-29 17:26

According to official Platform invoke data types mapping table DWORD corresponds to System.UInt32 in C#.

查看更多
在下西门庆
6楼-- · 2020-05-29 17:30

A DWORD is, by (Microsoft's) definition, an unsigned 32-bit integer. It should map to whichever type your compiler uses to represent that.

These days it's most likely an unsigned int, but that's not a portable implementation. I know you're using C#, but to give you an example in a language I'm more familiar with, a typical implementation in C might be:

#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
查看更多
迷人小祖宗
7楼-- · 2020-05-29 17:30

Sadly,read Registry must use int otherwise throw exception.this microsoft code:

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.");
      } 
    }
}

although release is REG_DWORD

查看更多
登录 后发表回答