2010-11-30 9 views
12

Zunächst wird eine Hintergrund Frage:Int vs IntPtr, wenn Sie einen Griff haben?

Im Allgemeinen, was ist der Unterschied zwischen int und IntPtr? Meine Vermutung ist, dass es sich eher um ein tatsächliches Objekt als um einen Wert wie int oder byte handelt. Angenommen, das ist wahr:

So sind sie nicht das Gleiche. Aber ich sehe Griffe als beides dargestellt.

  1. IntPtr: Control.Handle
  2. int (oder uint): Ein PInvoke Setup kann eine Rückkehr int und es funktioniert gut:

    [DllImport("coredll.dll", SetLastError = true)] 
    public static extern int GetForegroundWindow(); 
    private string GetActiveWindow() 
    { 
        const int nChars = 256; 
        int handle = 0; 
        StringBuilder Buff = new StringBuilder(nChars); 
    
        handle = CoreDLL.GetForegroundWindow(); 
    
        if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0) 
        { 
         return Buff.ToString(); 
        } 
    
        return ""; 
    } 
    

So int vs IntPtr? Ist es wichtig für Griffe? Kannst du beides benutzen?

Antwort

27

int ist 32 Bits lang. IntPtr ist so lang wie ein Zeiger für Ihre Architektur. Daher kann ein Zeiger in einem int nur auf 32-Bit-Systemen gespeichert werden, während er immer in einem IntPtr gespeichert werden kann.

Beachten Sie, dass Ihr „int als Rückgabewert“ Beispiel tut nicht ein int verwenden, um einen Zeiger zu halten, sondern nur einen numerischen Wert zu halten. Dies bedeutet jedoch nicht, dass int automatisch die richtige Größe hat: Der Autor dieser P/Invoke-Signatur sollte in die Dokumentation für GetForegroundWindow gegangen sein und sehen, dass er HWND zurückgibt.

Dann aus windef.h in der Platform SDK (oder this MSDN page) können wir sehen, dass ein HWND ein HANDLE ist das ein PVOID ist, das ... ist ein Zeiger!

Daher, soweit ich das beurteilen kann, ist diese Signatur falsch, da die Größe des Rückgabewerts GetForegroundWindow von der Architektur abhängt. So sollte es auch ein IntPtr sein.

Update:

Während es aus der obigen abgeleitet werden kann, ich denke, es lohnt sich ausdrücklich darauf hinweisen, dass:

  • Irrtümlich int statt IntPtr in 32-Bit-Anwendungen unter Verwendung nie ein Problem verursachen, auch wenn sie auf 64-Bit-Windows ausgeführt werden; Da die meisten Anwendungen zu diesem Zeitpunkt 32-Bit-fähig sind, können Sie solche Fehler sehr oft vermeiden.
  • Irrtümlich int statt IntPtr in 64-Bit-Anwendungen unter Verwendung nicht garantierten Probleme verursachen, da es durchaus möglich ist, dass die Werte in der Praxis in den 32 Bits der int passen angetroffen werden wird. Dies verringert weiter die Wahrscheinlichkeit, dass sich ein Fehler als ein Anwendungsfehler manifestiert.

daher für einen Fehler tatsächlich manifestieren gibt es drei Bedingungen, die zur gleichen Zeit erfüllt sein müssen:

  1. Ein int verwendet wird, wo ein IntPtr sein sollte.
  2. Das ausführbare Bild ist 64-Bit.
  3. Ein Wert, der von einem PInvoke-Aufruf zurückgegeben und als int gespeichert wird, ist tatsächlich größer als 32 Bit.
+1

Wenn Sie mit Top-Down-Speicherzuweisung laufen, dann können Sie die Bedingung 3, die sehr nützlich bei der Entwicklung –

+0

ist Ihr Beitrag ist Lebensretter Jon. Ich wünschte, ich könnte etwas tun, um mehr Aufmerksamkeit darauf zu lenken. Ich hatte mit einer Komponente, die sich unberechenbar verhielt, den absoluten Tiefpunkt erreicht, und Ihre Erkenntnisse brachten mich auf den richtigen Weg! Du hast meinen Tag gerettet. Nein. Meine Woche. Vielleicht meinen ganzen Monat, um es milde auszudrücken. Danke noch einmal! P.S .: Hier ist ein Beispiel, wie die Dinge mit Int vs IntPtr in den Süden gehen können: http://StackOverflow.com/Questions/15548016/Global-keyboard-hook/36188346#36188346 – xDisruptor