web-dev-qa-db-fra.com

Comment convertir IntPtr en int

Un handle de fenêtre, parfois de type int et d'autres heures de type IntPtr

int exemple:

 [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);    

IntPtr exemple:

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

Je ne semble pas être capable de convertir/casting de l'un à l'autre.

Quand j'essaie this.ProcessID = GetWindowThreadProcessId(windowHandle.ToInt32(),0) je reçois une erreur cannot implicitly convert from uint to int

10
E Mett

La signature SendMessage est 

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

ou ca

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);

N'échangez pas int et IntPtr. Ils sont presque équivalents seulement à 32 bits (de taille égale). À 64 bits, une IntPtr est presque équivalente à une long (taille égale)

La signature GetWindowThreadProcessId est

static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

ou

static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

Dans ce cas, une ref ou une out à "quelque chose" sont des références gérées à quelque chose, elles sont donc converties en interne en IntPtr lorsqu'elles sont passées à l'API native. Donc, out uint est, du point de vue de l'API native, équivalent à IntPtr.

Explication: l’important est que la "longueur" des paramètres soit la bonne. int et uint sont égaux pour l'API appelée. Et une IntPtr 32 bits est la même chose.

Notez que certains types (comme bool et char) ont un traitement spécial par le marshaler.

Vous ne devriez jamais convertir une int en une IntPtr. Gardez-le comme une IntPtr et vivez heureux. Si vous devez effectuer des opérations mathématiques non supportées par IntPtr, utilisez long (c'est 64 bits, donc jusqu'à ce que nous ayons Windows 128 , il n'y aura pas de problème :-)).

IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;
10
xanatos

Je pense que l'erreur cannot implicitly convert from uint to int fait référence à l'instruction =. Le champ this.ProcessID est int, mais GetWindowThreadProcessId renvoie uint.

Essaye ça

this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
1
RomanHotsiy

J'obtenais "Une opération arithmétique aboutissait à un débordement", chaque fois que j'étais:

IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler.ToInt32() == 0) //throws Exception

au lieu de:

IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler == IntPtr.Zero) //OK
0
DanielV