如何直接将Python的multiprocessing.Array转换为ctypes.c_void_p?
直接将multiprocessing.Array转换为ctypes.c_void_p的方法
当然可以跳过numpy这个中间步骤!其实multiprocessing.Array本身就是基于ctypes实现的,我们可以直接操作它的底层ctypes对象来获取内存地址,进而转换成ctypes.c_void_p,完全不需要借助numpy中转。
原理说明
multiprocessing.Array实例有一个_raw属性,它对应的就是底层的ctypes数组对象。我们可以用ctypes.addressof()函数获取这个ctypes数组的内存起始地址,然后把这个地址值直接赋值给ctypes.c_void_p类型的变量即可。
代码示例
直接转换的实现
import multiprocessing import ctypes # 创建一个共享内存数组(比如int类型,长度10) shared_arr = multiprocessing.Array('i', range(10)) # 直接获取底层ctypes数组的地址,转成c_void_p void_ptr = ctypes.c_void_p(ctypes.addressof(shared_arr._raw)) # 验证一下:可以把指针转回ctypes数组,看看数据是否一致 recovered_arr = ctypes.cast(void_ptr, ctypes.POINTER(ctypes.c_int * 10)).contents print(list(recovered_arr)) # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
对比原来的numpy中转方式
原来的方法大概是这样的:
import numpy as np # 先转numpy数组 np_arr = np.frombuffer(shared_arr.get_obj(), dtype=np.int32) # 再转c_void_p old_void_ptr = ctypes.c_void_p(np_arr.ctypes.data)
两种方式最终得到的指针是完全一致的,但直接操作ctypes的方法更高效,也省去了numpy的依赖。
注意事项
- 数据类型匹配:确保你创建
multiprocessing.Array时指定的类型(比如'i'对应ctypes.c_int)和后续转换时使用的ctypes类型一致,否则会出现内存访问错误。 - 跨进程指针有效性:如果要把这个
c_void_p传递给其他进程,需要注意:不同进程的虚拟地址空间是独立的,这个指针在其他进程中可能无法直接使用。如果是跨进程共享内存,建议还是直接传递multiprocessing.Array实例本身,或者使用共享内存的名称/句柄来重新获取,而不是传递指针。 - 内存生命周期:不要在
multiprocessing.Array被销毁后再使用对应的c_void_p指针,否则会导致悬空指针问题。
内容的提问来源于stack exchange,提问作者El Marce
相关产品推荐
相关产品推荐

