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

Python使用ctypes调用C++共享库函数报TypeError单字符类型错误

问题根因与修复方案

核心报错触发原因

你调用ctypes.c_char(binary)时,c_char类型仅支持传入单个字节的入参,但binary是读取的整段二进制文件内容,是长度远大于1的bytes对象,直接触发类型错误。对应C函数原型的第一个参数是const char *字符串指针,不需要用c_char转换,ctypes默认会将bytes对象自动转为const char*类型。

其他隐藏错误

  • NULL引用错误:Python原生没有NULL关键字,ctypes的空指针需要使用ctypes.NULL
  • 结构体传参错误:C函数的void *params是指针类型,直接传结构体对象会触发值传递,需要用ctypes.byref(func_param)取结构体指针传入
  • 二进制长度取值不够稳妥:读完文件后file.tell()虽然和全文件长度一致,但直接取len(binary)作为binsz入参兼容性更好
  • 参数硬编码风险:paramssz硬编码为4不符合结构体实际大小,你的virt_buff包含两个c_int,常规平台下总大小为8字节,直接用ctypes.sizeof(virt_buff)自动计算大小更稳妥
  • 缺少参数类型声明:ctypes默认的隐式类型转换容易触发隐藏内存错误,建议提前给函数声明argtypes明确参数类型

修复后完整代码

import ctypes
import pathlib

class virt_buff(ctypes.Structure):
  _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int)]

if __name__ == "__main__":
  libname = pathlib.Path().absolute() / "build/libfoo.so"
  c_lib = ctypes.CDLL(libname)
  
  # 显式声明函数参数类型,避免隐式转换错误
  c_lib.foo_func.argtypes = [
    ctypes.c_char_p,
    ctypes.c_size_t,
    ctypes.c_size_t,
    ctypes.c_void_p,
    ctypes.c_size_t,
    ctypes.c_void_p
  ]

  func_param = virt_buff(7, 0)

  with open("build/fib.bin", mode='rb') as file:
    binary = file.read()
  bin_len = len(binary)

  c_lib.foo_func(
    binary, 
    bin_len, 
    0x9000 + (bin_len & ~0xFFF), 
    ctypes.byref(func_param), 
    ctypes.sizeof(virt_buff),
    ctypes.NULL
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:36:08