DWORD应该映射到int还是uint?

时间:2022-09-14 20:25:14

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

当将Windows API(包括数据类型)转换为P/Invoke时,我应该将DWORD替换为int还是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.

它通常是没有签名的,但是我看到人们在任何地方都使用int(这仅仅是因为CLS的警告吗?)甚至。net框架本身也能做到这一点),所以我从来都不确定哪个才是正确的。

6 个解决方案

#1


40  

Well according to the MSDN DWORD is an unsigned integer with a range of 0 to 4294967295.

根据MSDN DWORD,它是一个无符号整数,范围为0到4294967295。

So ideally you should replace it with uint rather than int.

所以理想情况下,应该用uint代替int。

However, as you have spotted uint is non-CLS compliant so if your method is publicly visible you should use int and do the conversion. The corollary to that is that if your method isn't used outside your assembly you should mark it as internal rather than public. Then you'll be able use a uint.

但是,正如您所发现的uint是不兼容cls的,所以如果您的方法是公开可见的,您应该使用int并进行转换。其推论是,如果您的方法不在程序集之外使用,那么应该将其标记为内部的而不是公共的。然后就可以使用uint了。

#2


2  

It's unsigned so map it to uint.

它是无符号的,所以映射到uint。

#3


2  

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

使用int. Reason is,如果我用uint变量更改“AutoRestartShell”:

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:

注册表编辑器中的数据类型更改为“REG_SZ”。如果我要求返回的值为:

regKey.GetValue("AutoRestartShell");

a string gets returned.

一个字符串返回。

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

但是,如果我使用int变量更改“AutoRestartShell”:

regKey.SetValue("AutoRestartShell", intVariable);

The data type stays as "REG_DWORD".

数据类型保持为“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.

这为什么会发生?不知道。我只知道它有这个功能。逻辑当然会告诉我们应该使用uint,但是这会改变我们不希望的数据类型。

#4


1  

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

DWORD是(微软)定义的无符号32位整数。它应该映射到编译器用来表示它的任何类型。

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:

现在,它很可能是一个无符号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

#5


1  

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.

CLS遵从性警告仅适用于在程序集之外可见的P/Invoke方法,这通常意味着调用是公共的。如果方法在外部不可见,则可以使用uint。

#6


0  

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

遗憾的是,read Registry必须使用int,否则抛出异常。这个微软代码:

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

尽管释放REG_DWORD

#1


40  

Well according to the MSDN DWORD is an unsigned integer with a range of 0 to 4294967295.

根据MSDN DWORD,它是一个无符号整数,范围为0到4294967295。

So ideally you should replace it with uint rather than int.

所以理想情况下,应该用uint代替int。

However, as you have spotted uint is non-CLS compliant so if your method is publicly visible you should use int and do the conversion. The corollary to that is that if your method isn't used outside your assembly you should mark it as internal rather than public. Then you'll be able use a uint.

但是,正如您所发现的uint是不兼容cls的,所以如果您的方法是公开可见的,您应该使用int并进行转换。其推论是,如果您的方法不在程序集之外使用,那么应该将其标记为内部的而不是公共的。然后就可以使用uint了。

#2


2  

It's unsigned so map it to uint.

它是无符号的,所以映射到uint。

#3


2  

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

使用int. Reason is,如果我用uint变量更改“AutoRestartShell”:

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:

注册表编辑器中的数据类型更改为“REG_SZ”。如果我要求返回的值为:

regKey.GetValue("AutoRestartShell");

a string gets returned.

一个字符串返回。

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

但是,如果我使用int变量更改“AutoRestartShell”:

regKey.SetValue("AutoRestartShell", intVariable);

The data type stays as "REG_DWORD".

数据类型保持为“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.

这为什么会发生?不知道。我只知道它有这个功能。逻辑当然会告诉我们应该使用uint,但是这会改变我们不希望的数据类型。

#4


1  

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

DWORD是(微软)定义的无符号32位整数。它应该映射到编译器用来表示它的任何类型。

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:

现在,它很可能是一个无符号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

#5


1  

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.

CLS遵从性警告仅适用于在程序集之外可见的P/Invoke方法,这通常意味着调用是公共的。如果方法在外部不可见,则可以使用uint。

#6


0  

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

遗憾的是,read Registry必须使用int,否则抛出异常。这个微软代码:

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

尽管释放REG_DWORD