C#에서 발생하는 높은 수준의 문제는 로봇 제어 네트워크 패킷 (Ethercat)을 설명하는 데이터 구조의 단일 복사본을 만든 다음 해당 단일 데이터 구조를 사용하여 패킷 모음에서 데이터를 추출하는 것입니다.다른 유형의 배열을 반환하는 방법은 무엇입니까?
형식을 지정하는 전송 함수 또는 함수를 사용하여 데이터 구조의 암시 적 복제가 있으므로 누적 된 패킷의 데이터를 사용하려고 할 때 문제가 발생합니다. 목표를 설명하는 데 도움이되도록 필자는 내가 원했던 것을 수행하는 파이썬 프로그램을 작성했으며 C#에서이 작업을 수행 할 수 있는지 여부를 결정하는 데 도움을줍니다.
나를위한 C#의 도전은 가변 숫자 형식의 동종 컬렉션을 반환하는 단일 함수 "get_vector"입니다. 이 유형은 패킷 구조에서 정의되며 파이썬에서는 데이터 구조를 다시 정의하지 않고 사용할 수 있습니다.
import struct
# description of the complete packet
class PACKET_STRUCTURE :
# given a field name and a list of packets, return a vector
# this is the function that seems impossible in C# because the type of what is returned changes
def get_vector(self, name, packet_list):
# locate the packet definition by the name of the vector
result = [x for x in self.packet_def if x.field_name == name]
# without error checking, pos contains the location of the definition
pos = result[0].position;
# decode ALL the pacckets in the (encoded) packet list - returning a list of [time_sec, status, position
# in C# this step is similar to using Marshal.PtrToStructure to transform from byte[] to a struct
decoded_packet_list = [struct.unpack(self.fmt_str, packet) for packet in packet_list];
# from the list of decoded_packets, extract the desired field into its own list
vector = [decode[pos] for decode in decoded_packet_list]
# in C# this is similar to:
# var CS_vector = decode_packet_list.Select(item => item.field_name).ToArray();
# so far in C# there is no duplication of the packet structure.
# but after this point, assume I cast CS_vector to object and return it -
# to use the object, I've not figured out how to avoid casting it to some type of array
# eg double[], int32[]
return vector
def __init__(self):
self.packet_def = list();
self.fmt_str = "<";
self.cnt = 0;
# add description of single item to the structure
def add(self, struct_def) :
struct_def.position = len(self.packet_def);
self.packet_def.append(struct_def);
self.fmt_str += struct_def.type;
# create a simple packet based on a counter based on the defined structure
def make_packet(self):
vals = [self.cnt*10+x for x in range(0, len(self.packet_def))];
self.cnt += 1;
pk = apply(struct.pack, [self.fmt_str] + vals)
# print len(pk), ["%c" % x for x in pk]
return pk
def get_names(self):
return [packet_items.field_name for packet_items in self.packet_def];
# the description of a single field within the packet
class PACKET_ITEM :
def __init__(self, field_name, type):
self.field_name = field_name
self.type = type;
# self.offset = 0;
self.position = 0;
if __name__ == "__main__" :
INT32 = "l";
UINT16 = "H";
FLOAT = "f";
packet_def = PACKET_STRUCTURE();
# create an example packet structure - which is arbituary and could be anything - it could even be read from a file
# this definition is the ONLY defintion of the packet structure
# changes here require NO changes elsewhere in the program
packet_def.add(PACKET_ITEM("time_sec", FLOAT))
packet_def.add(PACKET_ITEM ("status",UINT16))
packet_def.add(PACKET_ITEM ("position",INT32))
# create a list of packets
pk_list = list()
for cnt in range(0,10) :
pk_list.append(packet_def.make_packet());
################################
# get the vectors without replicating the structure
# eg no int32[] position = (int32[])get_vector()
name_list = packet_def.get_names();
for name in name_list :
vector = packet_def.get_vector(name, pk_list);
print name, vector
저는이 질문을 만드는 데 많은 시간을 할애하고 문제를 해결하기 위해 수십 시간을 보냈습니다. 나에게 그것은 C#의 근본적인 문제 (또는 그것에 대한 나의 이해)를 다루는 것처럼 보입니다. 이것이 분명히 나쁜 질문 인 경우 부정적으로 투표했습니다. 친절하게도 이유를 알려주십시오. 그것이 그대로 나는 이유를 모른다. – pathfinder