34

将 Windows API(包括数据类型)转换为 P/Invoke 时,我应该将 DWORD 替换为intoruint吗?

它通常是未签名的,但我看到人们int到处都在使用(仅仅是因为 CLS 警告吗?甚至 .NET Framework 本身会这样做),所以我永远不确定哪个是正确的使用。

4

7 回答 7

45

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

因此,理想情况下,您应该将其替换为uint而不是int.

但是,正如您所发现的那样,uint它不符合 CLS,因此如果您的方法是公开可见的,您应该使用int并进行转换。其必然结果是,如果您的方法未在程序集之外使用,则应将其标记为internal而不是public. 然后你就可以使用uint.

于 2011-07-17T17:38:36.297 回答
2

它是未签名的,因此将其映射到uint.

于 2011-07-17T17:38:27.500 回答
1

根据(Microsoft)的定义,DWORD 是一个无符号的 32 位整数。它应该映射到您的编译器用来表示它的任何类型。

现在它很可能是一个无符号整数,但这不是一个可移植的实现。我知道您使用的是 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
于 2011-07-17T17:38:58.530 回答
1

只有当 P/Invoke 方法在程序集外部可见时,CLS 合规性警告才适用,这通常意味着调用是公开的。如果该方法在外部不可见,则可以使用uint.

于 2011-07-17T17:39:28.010 回答
1

使用整数。原因是,如果我用uint变量更改“AutoRestartShell” :

regKey.SetValue("AutoRestartShell", uintVariable);

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

regKey.GetValue("AutoRestartShell");

返回一个字符串

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

regKey.SetValue("AutoRestartShell", intVariable);

数据类型保持为"REG_DWORD"

为什么会这样?不知道。我所知道的是它确实如此。逻辑肯定会告诉我们应该使用 uint ,但这会改变我们不想要的数据类型。

于 2017-03-17T17:34:44.610 回答
0

可悲的是,读取注册表必须使用 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.");
      } 
    }
}

虽然版本是 REG_DWORD

于 2017-10-12T02:22:02.650 回答
0

根据官方平台调用数据类型映射表DWORD对应System.UInt32于C#中。

于 2020-03-29T19:40:54.557 回答