C# DWORD应该映射到int还是uint?
在将Windows API(包括数据类型)转换为p/Invoke时,我应该用C# DWORD应该映射到int还是uint?,c#,.net,winapi,pinvoke,dword,C#,.net,Winapi,Pinvoke,Dword,在将Windows API(包括数据类型)转换为p/Invoke时,我应该用int或uint替换DWORD吗 它通常是无符号的,但我看到人们到处都在使用int(这是因为CLS警告吗?确实如此),所以我从来都不确定使用哪个是正确的。它是无符号的,所以将它映射到uint嗯DWORD是一个范围为0到4294967295的无符号整数 因此,理想情况下,您应该将其替换为uint,而不是int 但是,正如您所发现的那样,uint不符合CLS,因此如果您的方法是公开可见的,您应该使用int并进行转换。由此推论
int
或uint
替换DWORD吗
它通常是无符号的,但我看到人们到处都在使用
int
(这是因为CLS警告吗?确实如此),所以我从来都不确定使用哪个是正确的。它是无符号的,所以将它映射到uint
嗯DWORD
是一个范围为0到4294967295的无符号整数
因此,理想情况下,您应该将其替换为uint
,而不是int
但是,正如您所发现的那样,uint
不符合CLS,因此如果您的方法是公开可见的,您应该使用int
并进行转换。由此推论,如果您的方法未在程序集外部使用,则应将其标记为internal
,而不是public
。然后您就可以使用uint
根据(微软)的定义,DWORD是一个无符号32位整数。它应该映射到编译器用来表示它的任何类型
现在它很可能是一个无符号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 compliance警告仅在p/Invoke方法在程序集外部可见时适用,这通常意味着调用是公共的。如果该方法外部不可见,则可以使用
uint
使用int。原因是,如果我使用uint变量更改“AutoRestartShell”:
regKey.SetValue("AutoRestartShell", uintVariable);
regKey.SetValue("AutoRestartShell", intVariable);
注册表编辑器中的数据类型更改为“REG_SZ”。如果我要求返回该值,并附带:
regKey.GetValue("AutoRestartShell");
返回一个字符串
但是,如果我使用int变量更改了“AutoRestartShell”:
regKey.SetValue("AutoRestartShell", uintVariable);
regKey.SetValue("AutoRestartShell", intVariable);
数据类型保持为“REG\u DWORD”
为什么会发生这种情况?不知道。我所知道的是它确实如此。逻辑当然会告诉我们应该使用uint,但这会改变我们不想要的数据类型。遗憾的是,读取注册表必须使用int,否则会引发异常。此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.");
}
}
}
尽管根据官方映射表,release是REG_DWORD但DWORD对应于
系统。UInt32
在C中。但是,在C中,uint
和int
是32位整数。但是,在C语言中,诸如int
和long
之类的基本数据类型在编译器之间并不一致,这是正确的。但是,只有在Microsoft未定义的函数或API中使用DWORD
时,这才是问题所在,根据定义,DWORD
是32位无符号整数。在Windows上,C int和long始终是32位的。我想我担心的是,(1)与框架不一致,(2)不符合CLS。我应该忽略这一点吗?.NET的行为或完全不相关的部分与封送WinApi类型有什么关系?原因相同,两个应用程序不能通过一个发送整数相互通信,而另一个需要字符串,反之亦然。至于uint或int是否会在这里产生实际的影响,我不知道。这只是一个观察。我认为最好不要改变那些不需要改变的东西。看起来罪魁祸首是私人的CalculateValueKind方法。它只是不确认uint
,但也不知道short
或其他数字类型。但是我认为点公共API应该比不符合CLS的类型更重要地处理符合CLS的类型。CLR实际上不区分int
和uint
。