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

如何在Python中更新传给C DLL的LP_c_ubyte缓冲区?

解决方法:用ctypes更新c_ubyte数组并传入DLL回调

我来帮你搞定这个问题!其实用ctypes操作c_ubyte数组更新字节非常直接,核心就是像操作Python列表一样通过索引修改元素,确保在调用DLL的DoCallBack函数前完成更新即可。下面是完整的实操流程和代码示例:

1. 先做好DLL和回调的类型定义

首先得把DLL函数和回调函数的原型定义清楚,避免类型不匹配导致的内存问题:

import ctypes

# 定义回调函数的原型:假设回调接收c_ubyte数组指针和数组长度
CALLBACK_FUNC = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int)

# 加载你的目标DLL
my_dll = ctypes.CDLL("your_target_dll.dll")

# 给DoCallBack函数指定参数类型和返回值类型
my_dll.DoCallBack.argtypes = [CALLBACK_FUNC, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int]
my_dll.DoCallBack.restype = None

2. 创建并更新c_ubyte数组

创建固定长度的c_ubyte数组后,直接通过索引赋值就能更新单个字节:

# 比如创建一个长度为6的c_ubyte数组
array_len = 6
connectionString = (ctypes.c_ubyte * array_len)()

# 批量填充字节:比如把1-6逐个塞进去
for idx in range(array_len):
    connectionString[idx] = idx + 1  # 此时数组元素为[1,2,3,4,5,6]

# 也可以单独修改某个字节,比如把第3个元素改成100
connectionString[2] = 100

3. 如果需要在Python回调中更新数组

要是你的需求是在Python回调函数里收到数组后再更新(让DLL后续使用),可以通过指针转换来操作数组:

def my_python_callback(arr_ptr, length):
    # 将指针转换成可直接操作的数组对象
    target_arr = ctypes.cast(arr_ptr, ctypes.POINTER(ctypes.c_ubyte * length)).contents
    # 更新单个元素
    target_arr[0] = 255
    # 或者批量更新,比如每个字节加1
    for idx in range(length):
        target_arr[idx] = target_arr[idx] + 1

# 将Python函数转换成C可识别的回调类型
c_compatible_callback = CALLBACK_FUNC(my_python_callback)

4. 调用DLL的DoCallBack函数

把更新好的数组和回调传入DLL即可:

# 传入提前更新完毕的connectionString数组
my_dll.DoCallBack(c_compatible_callback, connectionString, array_len)

几个关键注意事项

  • 数组长度要匹配:确保你创建的数组长度和DLL预期的一致,不然容易出现越界访问的问题。
  • 类型定义不能省:一定要用argtypes和restype给DLL函数指定类型,这能避免很多莫名其妙的内存错误。
  • 回调对象要保活:如果DLL会异步调用回调,记得把c_compatible_callback存成全局变量或者类属性,防止被Python垃圾回收掉。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:51:42