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

如何将Python bytes转换为ctypes void指针调用C函数

Python调用C函数传递bytes二进制数据方案

使用ctypes库调用C接口时,针对void*缓冲区+缓冲区长度的函数签名,不需要对bytes对象做UTF-8编码类的字符串转换,按以下两种场景处理即可:

  • 场景1:C函数仅读取缓冲区内容,不会修改内存
    ctypes原生兼容bytes类型的参数传递,只要提前声明好函数的参数类型,直接传入bytes对象和len(你的bytes对象)作为长度即可,不会因为二进制数据中包含\x00空字节出现截断问题。

  • 场景2:C函数会向传入的缓冲区写入/修改内容
    Python的bytes是不可变对象,内存区域只读,直接传入会触发段错误导致进程崩溃,需要先用ctypes.create_string_buffer()申请可写内存,把二进制数据拷贝到缓冲区后再传参。

完整调用示例

import ctypes

# 加载编译好的C动态库,Windows替换为.dll后缀,macOS替换为.dylib后缀
c_lib = ctypes.CDLL("./your_c_lib.so")

# 必须显式声明函数的参数类型、返回值类型,避免ctypes自动类型推导出错
c_lib.myfunc.argtypes = [ctypes.c_void_p, ctypes.c_int]
c_lib.myfunc.restype = ctypes.c_char_p

# 从文件读取二进制数据
with open("target_file.bin", "rb") as f:
    bin_content = f.read()

# 只读场景调用
ret = c_lib.myfunc(bin_content, len(bin_content))

# 可写场景调用:创建和原数据等长的可写缓冲区,自动填充原二进制内容
write_buf = ctypes.create_string_buffer(bin_content, len(bin_content))
ret = c_lib.myfunc(ctypes.cast(write_buf, ctypes.c_void_p), len(bin_content))
# 调用完成后,可通过write_buf.raw获取修改后的完整二进制数据
modified_bin = write_buf.raw

注意事项

  1. 禁止直接将bytes对象传入会修改入参内存的C函数,必现崩溃。
  2. 必须显式配置argtypes和restype,否则64位环境下很容易因为指针长度不匹配出现内存访问错误。
  3. 如果C函数要求的缓冲区长度大于当前二进制数据长度,create_string_buffer初始化时直接传入目标长度即可,超出原数据的内存空间会自动填充0。

内容的提问来源于stack exchange,提问作者K.F. Adams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:12:25