c# - ¿Debería DWORD mapear a int o uint?
.net winapi (6)
Al traducir la API de Windows (incluidos los tipos de datos) a P / Invoke, ¿debo reemplazar DWORD con int
o uint
?
Normalmente no tiene firma, pero veo personas que usan int
todas partes (¿es solo por la advertencia de CLS? Incluso el propio .NET Framework lo hace), así que nunca estoy seguro de cuál es la correcta para usar.
Bueno, de acuerdo con el MSDN DWORD
es un entero sin signo con un rango de 0 a 4294967295.
Entonces, idealmente, debes reemplazarlo por uint
lugar de int
.
Sin embargo, como ha detectado, uint
no cumple con CLS, por lo tanto, si su método es públicamente visible, debe usar int
y realizar la conversión. El corolario de eso es que si su método no se usa fuera de su ensamblaje, debe marcarlo como internal
lugar de public
. Entonces podrás usar un uint
.
La advertencia de cumplimiento de CLS se aplica solo si el método P / Invocar está visible fuera del ensamblaje, lo que generalmente significa que la llamada es pública. Si el método no es visible externamente, entonces es aceptable usar uint
.
Lamentablemente, leer el Registro debe utilizar int. De lo contrario arrojar exception.this código de 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.");
}
}
}
aunque la versión es REG_DWORD
No está firmado, así que uint
a uint
.
Un DWORD es, según la definición (de Microsoft), un entero sin signo de 32 bits. Debe correlacionarse con el tipo que use su compilador para representar eso.
En la actualidad, lo más probable es que sea una int sin firmar, pero esa no es una implementación portátil. Sé que estás usando C #, pero para darte un ejemplo en un idioma con el que estoy más familiarizado, una implementación típica en C podría ser:
#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
Use int. Motivo de ser, si cambio "AutoRestartShell" con una variable uint :
regKey.SetValue("AutoRestartShell", uintVariable);
el tipo de datos en el Editor del registro cambia a "REG_SZ" . Si solicito que se devuelva ese valor con:
regKey.GetValue("AutoRestartShell");
se devuelve una cadena
Sin embargo, si cambio "AutoRestartShell" con una variable int :
regKey.SetValue("AutoRestartShell", intVariable);
El tipo de datos permanece como "REG_DWORD" .
¿Por qué pasó esto? Ni idea. Todo lo que sé es que sí. La lógica ciertamente nos diría que debería usarse, pero eso cambia el tipo de datos que no queremos.