我怎样才能获得嵌套到另一个结构中的结构的引用,以递归地调用一个函数并处理整个结构?
我正在编写一个C#函数来计算C#结构体的大小,如果用C编写相同的结构体。因此,代码的目标是计算接收到的C#结构的C结构的大小。所接收的C#结构可以具有其他嵌套结构以及位域变量。C#不实现位域,所以我不得不使用属性以某种方式实现位域(我不能直接使用Marshal.SizeOf(my_struct)):
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct struct_b{// typedef struct __attribute__((packed)){
[BitfieldLength(1)]
public byte flag_a;// uint8_t flag_a :1;
[BitfieldLength(1)]
public byte flag_b;// uint8_t flag_b :1;
[BitfieldLength(2)]
public byte flag_c;// uint8_t flag_c :2;
[BitfieldLength(1)]
public byte flag_d;// uint8_t flag_d :1;
[BitfieldLength(3)]
public byte reserved;// uint8_t reserved :3;
public float measure_1;//float measure_1
public float measure_2;//float measure_2
public UInt32 value_1; // uint32_t value_1;
}// struct_b;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct struct_a{
// typedef struct __attribute__((packed)){
public Int16 i_value_a;// int16_t i_value_a;
public struct_b struct_field_b; //struct_b struct_field_b;
}// struct_a
这是我想递归调用的函数,我需要从它访问嵌套结构。它在没有其他嵌套结构的情况下工作,但我不想添加计算包含其他嵌套结构的结构的大小的功能,但我不知道如何获得具有嵌套结构的信息和父结构的字段的对象:
public static int SizeInPackedBytes(object structure, int i_start_idx, ref string str_parsed_struct){
int i_bitset_counter = 0;
int i_num_bits = 0;
int i_byte_index = 0;
int i_aux = 0;
bool b_is_struct = false;
int i_field_idx = 0;
// get and then process all the fileds of the received object with the structure
i_bitset_counter = 0;
i_byte_index = 0;
i_field_idx = 0;
FieldInfo[] field_info_array = structure.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
for (i_field_idx = 0; i_field_idx < field_info_array.Count(); i_field_idx++){
FieldInfo field_info = field_info_array[i_field_idx];
// check if the currently processed field of the received struct corresponds to another nested struct: structs are ValueType not Primitive and not Enums ....
b_is_struct = (field_info.FieldType.IsValueType && !field_info.FieldType.IsPrimitive && !field_info.FieldType.IsEnum);// structs are Value Types but not Primitive Types and not Primitive Types
if (b_is_struct){
// >>> HERE: i don't know how to get the reference to the nested struct to recursivelly call again SizeInBytesPacked(object structure)
// something like:
// >> object nested_struct = f_info_array[i_field_idx]
// >> i_byte_index = i_byte_index + SizeInBytesPacked(nested_struct);
}else{
// the current processed field does not corresponds to a nested struct, so check its attributes to detect if it corresponds to a bitfield or to a standard value type field
object[] attrs = field_info.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
if (attrs.Length == 1){
// the current field corresponds to a bitset!
// get the number of bits of the current processed field defined in the corresponding [BitfieldLength(x)]
i_num_bits = ((BitfieldLengthAttribute)attrs[0]).Length;
str_parsed_struct = str_parsed_struct + "[" + (i_start_idx + i_byte_index).ToString("D3") + "] Size: " + i_num_bits.ToString("D3") + " bits \"" + field_info.Name + "\" bit " + i_bitset_counter + " to " + ((i_bitset_counter + i_num_bits) % 8) + "\r\n";
i_bitset_counter = i_bitset_counter + i_num_bits;
// if the i_bitset_counter is beyond the current byte index then place the byte index
// at the end of the current field according to the size of the field
if (i_bitset_counter >= 8)
{
// started a new bitset
i_byte_index = i_byte_index + (int)(i_bitset_counter / 8);
i_bitset_counter = i_bitset_counter % 8;
}//if
}else{
// current field type is not a bitset
// if the previous field was a bitset which did not have the 'reserved' bits
// properly set, then try to byte-realign the following field
if (i_bitset_counter != 0){
i_byte_index++;
}
i_bitset_counter = 0;// reset the var used to count the bits in the bitsets
var struct_field_value = field_info.GetValue(structure);
Type test = struct_field_value.GetType();
i_aux = Marshal.SizeOf(test);
str_parsed_struct = str_parsed_struct + "[" + (i_start_idx + i_byte_index).ToString("D3") + "] Size: " + i_aux.ToString("D3") + " bytes \"" + field_info.Name + "\" \r\n";
i_byte_index = i_byte_index + i_aux;
}//if
}//if
}//for
...
}//SizeInPackedBytes
我想在接收到的结构中获取嵌套结构的引用,将它们存储在一个对象中,并递归调用前面的函数来处理它们。换句话说,我如何从FieldInfo变量中获取一个结构体,我知道它引用了一个结构体,类似于这样:
FieldInfo field_local = f_info_array[i_field_idx];
object nested_struct = field_local.GetValue(null);
1条答案
按热度按时间csbfibhn1#
最后,它比我想象的要容易,我只需要将前面函数中标记为“HERE >>”的块替换为:
这允许我获得嵌套结构,然后递归地将其传递给函数。