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

Python3.8用ctypes调用C库fread返回0的原因及二进制读取方法咨询

问题根本原因及解决方法

根本原因

  1. 字符串类型不兼容:Python3中字符串默认是Unicode类型(str),而C标准库的fopen函数需要接收字节类型的const char*参数。你代码里传的'rb'是Python3的str,直接传给fopen会导致参数类型错误,实际文件打开失败(虽代码判断了fp is None,但因ctypes类型匹配问题,fp未被正确识别为NULL,后续fread自然读不到内容)。Python2中str本身就是字节串,所以无此问题。
  2. argtypes定义错误:fopen的两个参数都是const char*,对应ctypes类型应为ctypes.c_char_p,而非ctypes.c_void_p。错误的argtypes会让ctypes无法正确转换Python对象到C类型,进一步加剧参数传递错误。

修正后的代码

import ctypes
import os

real_size = 282624
buffer = (ctypes.c_ubyte * real_size)()
length = real_size
file_path = "你的文件路径"  # 替换为实际文件路径

libc = ctypes.CDLL(ctypes.util.find_library("c"))

# 正确定义fopen的参数与返回值类型
libc.fopen.restype = ctypes.c_void_p
libc.fopen.argtypes = (ctypes.c_char_p, ctypes.c_char_p)
# 将文件路径和模式转为bytes类型传入
fp = libc.fopen(file_path.encode('utf-8'), b'rb')
if fp is None:
    raise OSError(f'Cannot open file {file_path}')

libc.fclose.argtypes = (ctypes.c_void_p,)

# 定义fseek的参数与返回值类型
libc.fseek.restype = ctypes.c_int
libc.fseek.argtypes = (ctypes.c_void_p, ctypes.c_long, ctypes.c_int)
if libc.fseek(fp, 0, os.SEEK_SET) != 0:
    libc.fclose(fp)
    raise IOError(f"fseek to 0 failed")

# 定义fread的参数与返回值类型
libc.fread.argtypes = (ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p)
libc.fread.restype = ctypes.c_size_t
bytes_read = libc.fread(ctypes.addressof(buffer), 1, length, fp)
print(f"Bytes read: {bytes_read}")

# 操作完成后关闭文件
libc.fclose(fp)

# 可选:将ctypes数组转为Python的bytes对象
data = bytes(buffer[:bytes_read])

使用fread读取二进制文件的正确步骤

  • 严格匹配参数类型:传给C函数的参数必须和C函数期望类型完全一致,Python3中字符串参数要转为bytes,同时正确设置argtypes和restype,这是ctypes调用C函数的核心要求。
  • 指定二进制打开模式:用b'rb'作为打开模式,明确以二进制只读方式打开,避免文本模式下的换行符转换、编码处理等干扰。
  • 检查每一步返回值:打开文件后检查fp是否为NULL,fseek后检查返回值是否为0,确保每一步操作成功,避免后续操作在错误状态下执行。
  • 读取后转换处理:读取到ctypes数组的内容,可通过bytes(buffer[:bytes_read])转为Python的bytes对象,方便后续业务处理。
  • 及时释放资源:操作完成后调用fclose关闭文件,避免资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:09:21