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

通过ctypes在Python调用C函数传递字节数组与直接C调用结果不一致问题

问题排查与解决

核心差异:数组初始化逻辑不一致

你的C代码与Python代码中,input、state数组的初始化行为完全不同,这是哈希结果不符的直接原因:

C代码的初始化规则

在C语言中:

uint8_t input[38] = {"0"};
uint8_t state[40] = {"0"};
  • 仅数组第一个元素被赋值为字符'0'(对应ASCII码0x30)
  • 数组剩余未初始化的元素会被自动置为0(C语言局部数组部分初始化的默认规则)

以input数组为例,实际内容是:[0x30, 0x00, 0x00, ..., 0x00](共38个元素,1个0x30,37个0x00)

Python代码的初始化逻辑

而你当前的Python代码:

input = b'00000000000000000000000000000000000000'  # 38个'0'字符
state = ctypes.create_string_buffer(b'0000000000000000000000000000000000000000', size=40)  # 40个'0'字符
  • 数组所有元素均为字符'0'(ASCII码0x30),没有0值填充的元素

修正后的Python代码

按照C的初始化逻辑调整Python代码,确保数组内容完全对齐:

import ctypes

sha = ctypes.CDLL('/path/to/lib/sha_lib.so')
func = sha.sha256_inc_finalize

# 显式指定参数与返回值类型,避免隐式类型错误
func.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_size_t]    
func.restype = None  # 若函数无返回值,必须显式声明

# 初始化output:第一个元素为'0',其余31个元素为0(与C代码一致)
out = ctypes.create_string_buffer(32)
out[0] = ord('0')

# 初始化state:第一个元素为'0',其余39个元素为0
state = ctypes.create_string_buffer(40)
state[0] = ord('0')

# 初始化input:第一个元素为'0',其余37个元素为0
input_buf = ctypes.create_string_buffer(38)
input_buf[0] = ord('0')

func(out, state, input_buf, 38)

# 按C的格式输出哈希结果
result = bytes(out).hex()
formatted_result = ' '.join([result[i:i+8] for i in range(0, len(result), 8)])
print(formatted_result)

额外注意事项

  • 显式声明返回值类型:如果sha256_inc_finalize是无返回值的void函数,必须设置func.restype = None,否则ctypes会默认将返回值当作int处理,可能破坏栈结构。
  • 严谨的类型匹配:若要完全对应C的uint8_t*,可以替换为ctypes.POINTER(ctypes.c_ubyte),比如:
    func.argtypes = [ctypes.POINTER(ctypes.c_ubyte), 
                     ctypes.POINTER(ctypes.c_ubyte), 
                     ctypes.POINTER(ctypes.c_ubyte), 
                     ctypes.c_size_t]
    
    此时数组可以用(ctypes.c_ubyte * 38)()创建,再设置第一个元素为ord('0')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:01:05