我不太习惯 python ctypes,如果这是一个天真的问题,很抱歉。我正在尝试复制一个结构,这是我的代码:
from ctypes import *
class Group(Structure):
_fields_ = [
("ChSize", c_uint32*9),
("DataChannel", POINTER(c_float)*9),
("TriggerTimeLag", c_uint32),
("StartIndexCell", c_uint16)]
def deepcopy(self):
copy = Group()
for n_channel in range(9):
data_buffer = c_float*self.ChSize[n_channel]
memmove(
addressof(data_buffer),
self.DataChannel[n_channel],
self.ChSize[n_channel]*sizeof(c_float),
)
copy.ChSize[n_channel] = self.ChSize[n_channel]
copy.DataChannel[n_channel] = addressof(data_buffer)
copy.TriggerTimeLag = self.TriggerTimeLag
copy.StartIndexCell = self.StartIndexCell
return copy
但是,当我尝试使用它时,我发现
TypeError: invalid type
创建
Group
对象的全新副本的正确方法是什么?
假设九个大小代表九个DataChannel指针各自指向的每个浮点数组的长度:
import ctypes as ct
class Group(ct.Structure):
_fields_ = (('ChSize', ct.c_uint32 * 9),
('DataChannel', ct.POINTER(ct.c_float) * 9),
('TriggerTimeLag', ct.c_uint32),
('StartIndexCell', ct.c_uint16))
def __repr__(self):
s = f'Group(ChSize={self.ChSize[:]}, TriggerTimeLag={self.TriggerTimeLag}, StartIndexCell={self.StartIndexCell})\n'
for i in range(9):
s += f' DataChannel[{i}] = {self.DataChannel[i][:self.ChSize[i]]}\n'
return s
def deepcopy(self):
copy = Group.from_buffer_copy(self) # make a shallow copy
# Note: at this point the data channels point to the original group
for i, (size, channel) in enumerate(zip(self.ChSize, self.DataChannel)): # iterate channels
data = (ct.c_float * size)(*channel[:size]) # make a copy of the data for a channel
copy.DataChannel[i] = ct.cast(data, ct.POINTER(ct.c_float)) # store a pointer to that data in the copy
return copy
# Validation
# Create, initialize and display a group
group = Group()
group.ChSize[:] = [1,2,3,4,5,6,7,8,9]
for i, size in enumerate(group.ChSize):
data = (ct.c_float * size)(*[1.5 * n for n in range(size)])
group.DataChannel[i] = ct.cast(data, ct.POINTER(ct.c_float))
group.TriggerTimeLag = 123
group.StartIndexCell = 456
print(group)
copy = group.deepcopy() # make a copy
# Zero out the channels of the original
group.ChSize[:] = [0] * 9
group.DataChannel[:] = [None] * 9
print(group) # display zeroed-out group
print(copy) # display copy
输出:
Group(ChSize=[1, 2, 3, 4, 5, 6, 7, 8, 9], TriggerTimeLag=123, StartIndexCell=456)
DataChannel[0] = [0.0]
DataChannel[1] = [0.0, 1.5]
DataChannel[2] = [0.0, 1.5, 3.0]
DataChannel[3] = [0.0, 1.5, 3.0, 4.5]
DataChannel[4] = [0.0, 1.5, 3.0, 4.5, 6.0]
DataChannel[5] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5]
DataChannel[6] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0]
DataChannel[7] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5]
DataChannel[8] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0]
Group(ChSize=[0, 0, 0, 0, 0, 0, 0, 0, 0], TriggerTimeLag=123, StartIndexCell=456)
DataChannel[0] = []
DataChannel[1] = []
DataChannel[2] = []
DataChannel[3] = []
DataChannel[4] = []
DataChannel[5] = []
DataChannel[6] = []
DataChannel[7] = []
DataChannel[8] = []
Group(ChSize=[1, 2, 3, 4, 5, 6, 7, 8, 9], TriggerTimeLag=123, StartIndexCell=456)
DataChannel[0] = [0.0]
DataChannel[1] = [0.0, 1.5]
DataChannel[2] = [0.0, 1.5, 3.0]
DataChannel[3] = [0.0, 1.5, 3.0, 4.5]
DataChannel[4] = [0.0, 1.5, 3.0, 4.5, 6.0]
DataChannel[5] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5]
DataChannel[6] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0]
DataChannel[7] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5]
DataChannel[8] = [0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0]