【发布时间】:2018-03-02 12:34:53
【问题描述】:
我正在尝试在 64 位 python 应用程序中使用来自 kernel32 的 InterlockedExchange。
这是我理想的工作代码:
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)
但是,这是我使用 64 位 python 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 位的工作原理与我预期的一样:
C:\Users\Douglas Sexton\Source\Repos\SharedMemory\SharedMemory\Python>"C:\Program Files (x86)\Python36\python.exe" interlocked3.py
5
5
68
我也尝试从序数访问:
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)
这对于 32 位具有相同的输出,但对于 64 位,这是输出:
C:\Users\Douglas Sexton\Source\Repos\SharedMemory\SharedMemory\Python>python interlocked.py
5
0
0
我现在尝试了几种不同的方法从 python 64 访问 InterlockedExchange,但似乎都遇到了同样的问题。我已经能够使用 python 64 中的其他 kernel32 函数。这让我发疯。
【问题讨论】:
-
显然在 x64 ABI 中,
InterlockedExchange仅可用作编译器内在_InterlockedExchange。 -
顺便说一句,对于 Windows API,最好使用
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)而不是ctypes.windll.kernel32。这避免了在全局windll对象上缓存原型,并且还使 ctypes 能够保护 WinAPI 上一个错误值。在这种情况下,最后一个错误值可通过ctypes.get_last_error()获得,您可以通过ctypes.set_last_error(value)预先设置它。对于失败的调用,通过raise ctypes.WinError(ctypes.get_last_error())引发异常。 -
@eryksun 感谢您的评论。我想我可以创建一个 dll,它只是 InterlockedExchange 的包装器并使用它?
-
如果您必须构建一个包装器,您也可以将问题划分为将相关方面移动到 C/C++ 中。 CFFI 和 Cython 使编写扩展模块变得更容易,并且可能更适合您的需求。
标签: windows python-3.x 64-bit ctypes kernel32