You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python ctypes调用kernel32.dll中InterlockedExchange函数失败求助

解决ctypes调用InterlockedExchange找不到函数的问题

问题原因

  • 调用约定不匹配:kernel32.dll中的函数采用stdcall调用约定,而你用ctypes.CDLL加载时默认是cdecl约定,导致无法匹配导出函数。
  • 路径转义问题:代码里的'C:\Windows\System32\kernel32.dll'中,\W和\S会被Python解析为转义字符,可能导致dll路径识别错误。
  • 未声明函数签名:即使找到函数,不指定参数和返回值类型,后续调用也容易出现崩溃或错误结果。

修正后的代码

import ctypes

# 用原始字符串避免转义,或把反斜杠替换成双反斜杠
dll_path = r'C:\Windows\System32\kernel32.dll'
# 必须用WinDLL加载kernel32,适配stdcall调用约定
kernel32 = ctypes.WinDLL(dll_path, use_last_error=True)

# 声明32位整数版本的InterlockedExchange参数和返回值类型
kernel32.InterlockedExchange.argtypes = [ctypes.POINTER(ctypes.c_long), ctypes.c_long]
kernel32.InterlockedExchange.restype = ctypes.c_long

# 若需操作64位整数,改用InterlockedExchange64并替换类型
# kernel32.InterlockedExchange64.argtypes = [ctypes.POINTER(ctypes.c_longlong), ctypes.c_longlong]
# kernel32.InterlockedExchange64.restype = ctypes.c_longlong

关键说明

  • WinDLL vs CDLL:Windows系统自带dll(如kernel32、user32)几乎都用stdcall约定,必须用ctypes.WinDLL加载;CDLL仅适用于自定义的cdecl约定库。
  • 显式声明函数类型:指定argtypes和restype是ctypes的最佳实践,能避免因类型不匹配引发的各种异常。
  • 64位场景适配:如果程序运行在64位系统且需操作64位共享变量,直接使用InterlockedExchange64即可,用法与32位版本一致。

结合mmap实现跨服务原子操作示例

假设已通过mmap创建共享内存,可按以下方式实现原子交换:

import mmap

# 创建存储32位整数的共享内存
shared_mem = mmap.mmap(-1, ctypes.sizeof(ctypes.c_long), tagname='MySharedMemory', access=mmap.ACCESS_WRITE)
# 将共享内存转为可直接操作的c_long变量
shared_var = ctypes.c_long.from_buffer(shared_mem)

# 原子交换:将shared_var的值替换为100,返回旧值
old_value = kernel32.InterlockedExchange(ctypes.byref(shared_var), 100)
print(f"旧值: {old_value}, 新值: {shared_var.value}")

内容的提问来源于stack exchange,提问作者sumit singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 03:01:05