Передать любой элемент структуры в функцию

#c #function #pointers #struct

#c #функция #указатели #структура

Вопрос:

У меня есть следующая структура:

 typedef struct
{
    uint8_t number;
    uint8_t user_bank;
    uint8_t temperature;
    float acc_xyz[3];
    float gyro_xyz[3];
    float mag_xyz[3];
    float acc_bias[3];
    float gyro_bias[3];
    float quaternions[4];
    char *orientation_of_IMU;
    char *component_orientation_on_pcb;
} Sensor;
  

Я заинтересован в представлении некоторых элементов с плавающей запятой в виде байтов, чтобы я мог передавать их через SPI. Пока у меня есть эти функции, которые позволяют мне переносить 4 кватерниона с плавающей запятой и возвращать 16 байт в буфер.

 typedef char byte;
void floatToByteArray(float f, byte buf[4])
{
    memcpy(buf, amp;f, sizeof(f));
}

//Function that takes float quaternions from a sensor struct, and returns their values, represented as bytes for easier SPI transfer.

void wrap_quaternions(Sensor* imu, int8_t *buff)
{
    for (int i = 0; i < 4; i  )
    {
        floatToByteArray(imu->quaternions[i], amp;buff[4*i]);
    }
}

  

Теперь я заинтересован в его обобщении, поэтому я могу взять любой из моих элементов массива с плавающей запятой в структуре Sensor и обернуть их соответствующим образом. Я хотел бы иметь возможность вызывать функцию floatToByteArray с аргументом imu-> float_member, но я не могу этого сделать. Тогда я мог бы изменить число 4 на sizeof(float_member).

Есть ли обходной путь для этого?

Комментарии:

1. Замените Sensor* imu аргумент на int cnt, float *arr[cnt] . Затем вы можете передать, например 3, sensor->gyro_bias , или вы могли бы передать sizeof(sensor->gyro_bias)/sizeof(float), sensor->gyro_bias .

2. Потрясающе! Я добавлю это и создам вложенную структуру в моей структуре датчиков для обернутых данных. Затем я буду использовать аргументы sizeof(sensor->acc_bias), sensor ->acc_bias, sensor -> wrapped_data -> acc_bias_wrapped . Это должно сработать, верно?

3. Хм. Я пробовал, но, похоже, это не работает. Может быть, вы можете проверить мой другой комментарий?

4. Ой, извините, я перепутал свой пример. float *arr[cnt] должно быть только float arr[cnt] в списке аргументов.

Ответ №1:

Вы пытались использовать свой параметр float в качестве указателя? Указатели очень удобны для подобных ситуаций.

Ответ №2:

Я попытался реализовать идею Toms, но, похоже, я все еще получаю сообщение об ошибке, поскольку программа ведет себя не так, как должна. Может быть, один из вас может помочь.

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
 
typedef char byte;
void floatToByteArray(float f, byte buf[4])
{
    memcpy(buf, amp;f, sizeof(f));
}
 
 void wrap_floatData(int cnt, float *arr[cnt], int8_t *buff)
{
    for (int i = 0; i < cnt; i  )
    {
        floatToByteArray(*arr[i], amp;buff[cnt*i]);

    }
}


struct Sensor_Data_Wrapped
{
    int8_t quaternions_wrapped[16];
    int8_t mag_xyz_wrapped[12];
    int8_t acc_bias_wrapped[12];
    int8_t gyro_bias_wrapped[12];
};

typedef struct
{
    uint8_t number;
    uint8_t user_bank;
    uint8_t temperature;
    float acc_xyz[3];
    float gyro_xyz[3];
    float mag_xyz[3];
    float acc_bias[3];
    float gyro_bias[3];
    float quaternions[4];
    char *orientation_of_IMU;
    char *component_orientation_on_pcb;
    //struct Sensor_Data_Wrapped wrapped_data;
} Sensor;


Sensor IMU1;
Sensor IMU2; 
int8_t Wrapped_IMU1_bias[12];
 
int main(void) 
{
    
    Wrapped_IMU1_bias[1] = 25;
    
    IMU1.gyro_bias[0] =119.0;
    IMU1.gyro_bias[1] = 1349;
    IMU1.gyro_bias[2] = 5.2;


    
    wrap_floatData(3, IMU1.gyro_bias, Wrapped_IMU1_bias);

    
    for (int i = 0; i < 12; i  )
    {
                printf("Byte is %d", Wrapped_IMU1_bias[i]);
                printf("n");

    }

return 0; 
    
}
  

Ошибки:

main.c:89:20: предупреждение: передача аргумента 2 ‘wrap_floatData’ из несовместимого типа указателя [-Wincompatible-pointer-types] main.c:39:7: примечание: ожидается ‘float **’, но аргумент имеет тип ‘float *’ Ошибка сегментации (сброс ядра)

Комментарии:

1. Ой, извините, я перепутал свой пример. float *arr[cnt] должно быть только float arr[cnt] в списке аргументов.

2. Неплохо. Теперь все хорошо. Я вижу, что функция sizeof дает мне 12, поскольку массивы состоят из 3 чисел с плавающей запятой (12 байт). Я определил свою собственную функцию N_ELEMS(x) (sizeof(x) / sizeof((x)[0])) N_elements, которая дает мне желаемый результат. Спасибо за помощь!