web-dev-qa-db-ger.com

Soll DWORD auf int oder uint abgebildet werden?

Sollte ich beim Übersetzen der Windows-API (einschließlich Datentypen) in P/Invoke DWORD durch int oder uint ersetzen?

Normalerweise ist es nicht signiert, aber ich sehe Leute, die stattdessen int verwenden (liegt das nur an der CLS-Warnung? sogar am .NET Framework selbst macht dies ), und ich bin mir nie ganz sicher, welche ist der richtige zu verwenden.

29
Mehrdad

Nun laut MSDNDWORD ist eine vorzeichenlose Ganzzahl mit einem Bereich von 0 bis 4294967295.

Idealerweise sollten Sie es durch uint anstelle von int ersetzen.

Da Sie jedoch festgestellt haben, dass uint nicht mit CLS kompatibel ist, sollten Sie, wenn Ihre Methode öffentlich sichtbar ist, int verwenden und die Konvertierung durchführen. Die Folge davon ist, dass, wenn Ihre Methode nicht außerhalb Ihrer Assembly verwendet wird, Sie sie als internal statt als public markieren sollten. Dann können Sie eine uint verwenden.

42
ChrisF

Verwenden Sie int. Grund ist, wenn ich "AutoRestartShell" mit einer uint Variable ändere:

regKey.SetValue("AutoRestartShell", uintVariable);

der Datentyp im Registry Editor ändert sich nach "REG_SZ" . Wenn ich darum bittet, dass dieser Wert mit zurückgegeben wird:

regKey.GetValue("AutoRestartShell");

ein String wird zurückgegeben.

Wenn ich jedoch "AutoRestartShell" mit einer int Variable ändere:

regKey.SetValue("AutoRestartShell", intVariable);

Der Datentyp bleibt als "REG_DWORD" .

Warum passiert das? Keine Ahnung. Ich weiß nur, dass es das tut. Logic würde uns sicherlich sagen, dass Uint verwendet werden sollte, aber das den Datentyp ändert, den wir nicht wollen.

2
Rehaan

Es ist nicht signiert, also ordnen Sie es uint zu.

2
David Heffernan

Ein DWORD ist nach Definition von Microsoft eine vorzeichenlose 32-Bit-Ganzzahl. Es sollte dem Typ entsprechen, den Ihr Compiler verwendet, um dies darzustellen.

Heutzutage ist es höchstwahrscheinlich ein unsigniertes int, aber das ist keine portable Implementierung. Ich weiß, dass Sie C # verwenden, aber um Ihnen ein Beispiel in einer mir bekannten Sprache zu geben, könnte eine typische Implementierung in C Folgendes sein:

#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
1
Adam Liss

Die CLS-Konformitätswarnung gilt nur, wenn die P/Invoke-Methode außerhalb der Assembly sichtbar ist. Dies bedeutet im Allgemeinen, dass der Anruf öffentlich ist. Wenn die Methode von außen nicht sichtbar ist, kann uint verwendet werden.

1
Peter O.

Leider muss die Leseregistrierung int verwenden, sonst eine Ausnahme auslösen.

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

obwohl das Release REG_DWORD ist

0
fe263