Home > Back-end >  How to copy c arrays from one struct into another struct
How to copy c arrays from one struct into another struct

Time:06-29

I want to do a copy of arrays which are parts of one struct into another one. In other words I have one programm (Carmaker) accepting struct A and another one accepting struct B (Labview) and I need to convert them somehow.

Conversion of struct A --> struct B

#ifndef CONVERTERCPP2LV_ALGOBASETYPES_H
#define CONVERTERCPP2LV_ALGOBASETYPES_H

#include <cstdint>

namespace AlgoBaseTypes
{
    typedef float float32;
    typedef std::int32_t sint32;
    typedef std::uint32_t uint32;
    typedef std::int16_t sint16;
    typedef std::uint16_t uint16;
    typedef std::int8_t sint8;
    typedef std::uint8_t uint8;
    typedef std::uint64_t uint64;
    typedef std::int64_t sint64;
    typedef double float64;
    typedef std::uint8_t boolean;
#define FALSE AlgoBaseTypes::boolean {0}
#define TRUE AlgoBaseTypes::boolean {1}
}

#endif //CONVERTERCPP2LV_ALGOBASETYPES_H

Struct A:

typedef struct ts_InnovizContextData
{
    // firmware version as string
    ::AlgoBaseTypes::uint8 a_FirmwareVersion[20]{ 0 };
    // Indicates if the Data is integral or corrupted
    te_DataValidity E_DataValidity{ te_DataValidity::E_DataInvalid };
    ::AlgoBaseTypes::uint64 FrameCounter{ 0 };
    ::AlgoBaseTypes::uint64 TimestampMeasureStart{ 0 };
    // unique sensor ID
    ::AlgoBaseTypes::uint32 SensorId{ 0 };
    // The meaning of values of LidarState is defined in the following document (Chapter 6.1) 
    ::AlgoBaseTypes::uint8 LidarState{ 0 };     
    ::AlgoBaseTypes::uint8 LidarSubState{ 0 };
    // number of all Lidar detections in each LRF
    ::AlgoBaseTypes::uint32 a_NumDetections[4]{ 0 };
} ts_InnovizContextData;

typedef struct ts_InnovizDetectionData
{
    ts_InnovizContextData s_ContextData;
} ts_InnovizDetectionData;

Struct B:

typedef struct {
    int32_t dimSize;
    uint8_t* a_FirmwareVersion;
    } TD5;
typedef TD5 **TD5Hdl;

typedef struct {
    uint64_t FrameCounter;
    uint64_t TimestampMeasureStart;
    uint32_t SensorId;
    uint8_t LidarState;
    uint8_t LidarSubState;
    TD4Hdl a_NumDetections;
    TD5Hdl a_FirmwareVersion;
    uint16_t te_DataValidity;
    } TD3;

typedef struct {
    //TD2 ts_InterfaceVersion;
    TD3 ts_InnovizContextData;
    //TD6 ts_Detection;
    } TD1;

my first try is using memcpy

int main() {
    //Struct A
    InnovizDetectionData::ts_InnovizDetectionData Carmaker;
    //Struct B
    TD1 Labview;
    
    //Try1: does not work for arrays --> NULL as reference
    memcpy(&Labview, &Carmaker, sizeof(Carmaker));

    //improved try:works for simple structures
    memcpy(&Labview, &Carmaker, 22); // copy only 22 bytes

    //uint8_t arrayToCopy[20]={0};
    Labview.ts_InnovizContextData.a_FirmwareVersion.a_FirmwareVersion= uint_8[20]{0};
    Labview.ts_InnovizContextData.a_FirmwareVersion.dimSize = 20;
    //memcpy(&Labview.ts_InnovizContextData.a_NumDetections, &Carmaker.s_ContextData.a_NumDetections, sizeof(Carmaker.s_ContextData.a_NumDetections));
    //memcpy(&Labview.ts_InnovizContextData.a_FirmwareVersion.a_FirmwareVersion , &Carmaker.s_ContextData.a_FirmwareVersion, sizeof(Carmaker.s_ContextData.a_FirmwareVersion) * 20);
    return 0;
}

CodePudding user response:

I would probably just create an instance of struct B and manually go through each individual member of struct B and assign the equivalent value from struct A (remember value casting if value types differ).

You will need allocate the array members for B (a_FirmwareVersion and a_NumDetections) and then either memcpy or loop through because they are arrays.

Notice that a_FirmwareVersion in struct A has fixed size of 20 while struct B has varying size with dimSize. For A -> B conversion dimSize becomes always 20. If converting the other way around then you need stop at 20th byte.

Then wrap that into a function that takes struct A as input and returns struct B.

And if needed make another function for B -> A conversion with the same idea but the otherway around.

CodePudding user response:

Use std::array or std::vector and you can just assign the values. You will also gain memory management and move semantic for free.

  • Related