2017-09-21 4 views
0

J'essaie d'utiliser InterlockedExchange de kernel32 dans une application python 64 bits.Peut accéder à certaines fonctions kernel32 avec des ctypes en 32 bits mais pas en 64 bits

C'est le code que je voudrais idéalement avoir de travail:

import ctypes 
from ctypes import * 

interlockedValue = ctypes.c_long(5) 

print(interlockedValue.value) 

locked = ctypes.c_long(68) 
print(windll.kernel32.InterlockedExchange(byref(interlockedValue),locked)) 

print(interlockedValue.value) 

Cependant ceci est mon ouput avec python 64 bits 3.5.2:

C:\Users\Douglas Sexton\Source\Repos\SharedMemory\SharedMemory\Python>python interlocked3.py 
5 
Traceback (most recent call last): 
File "interlocked3.py", line 10, in <module> 
print(windll.kernel32.InterlockedExchange(byref(interlockedValue), locked)) 
File "C:\Program Files (x86)\Python35\lib\ctypes\__init__.py", line 360, in __getattr__ 
func = self.__getitem__(name) 
File "C:\Program Files (x86)\Python35\lib\ctypes\__init__.py", line 365, in __getitem__ 
func = self._FuncPtr((name_or_ordinal, self)) 
AttributeError: function 'InterlockedExchange' not found 

32 bits fonctionne comme j'attendre cependant:

C:\Users\Douglas Sexton\Source\Repos\SharedMemory\SharedMemory\Python>"C:\Program Files (x86)\Python36\python.exe" interlocked3.py 
5 
5 
68 

J'essayé d'accéder à de ordinale ainsi:

import ctypes 
from ctypes import * 

interlockedValue = ctypes.c_long(5) 

print(interlockedValue.value) 

locked = ctypes.c_long(68) 

print(windll.kernel32[868](byref(interlockedValue), locked)) 

print(interlockedValue.value) 

Cela a la même sortie 32 bits mais pour 64 bits, c'est la sortie:

C:\Users\Douglas Sexton\Source\Repos\SharedMemory\SharedMemory\Python>python interlocked.py 
5 
0 
0 

J'ai essayé quelques différentes façons d'accéder InterlockedExchange de python 64 maintenant et tous semblent courir dans le même problème. J'ai pu utiliser d'autres fonctions kernel32 de python 64. Cela me rend fou.

+0

Apparemment dans l'ABI x64, ['InterlockedExchange'] (https://msdn.microsoft.com/en-us/library/ms683590) est uniquement disponible en tant que compilateur intrinsèque [' _InterlockedExchange'] (https: // docs.microsoft.com/en-us/cpp/intrinsics/interlockedexchange-intrinsic-functions). – eryksun

+0

BTW, pour l'API Windows, il est préférable d'utiliser 'kernel32 = ctypes.WinDLL ('kernel32', use_last_error = True)' au lieu de 'ctypes.windll.kernel32'. Cela évite de mettre en cache des prototypes sur l'objet global 'windll' et permet également aux ctypes de protéger la dernière valeur d'erreur de WinAPI. Dans ce cas, la dernière valeur d'erreur est disponible via 'ctypes.get_last_error()', et vous pouvez la définir au préalable via 'ctypes.set_last_error (value)'. Pour un appel manqué, déclenchez une exception via 'raise ctypes.WinError (ctypes.get_last_error())'. – eryksun

+0

@eryksun merci pour votre commentaire. Je suppose que je pourrais créer une DLL qui est juste un emballage pour InterlockedExchange et l'utiliser? –

Répondre

0

Je n'ai pas eu besoin de cela pour le moment, mais j'ai été capable de créer un wrapper dll pour InterlockedExchange et l'utiliser avec succès à partir d'un processus 64.