prøver å kopiere struct medlemmer til å byte array ic

stemmer
6

Jeg forsøker å kopiere medlemmer av en struct som inneholder en blanding av ints, røye tallet og rekker av tegn i en byte array å sende til en seriell linje. Så langt jeg har

struct msg_on_send
{
    char descriptor_msg[5];
    int  address;
    char space;
    char cmdmsg[5];
    char CR;
    char LF;
};

void switch_output_on()
{
    int member;
    struct msg_on_send SendMsg_on[sizeof member] =
     {

    };
    unsigned char buffer [ sizeof SendMsg_on[0] ];
    showbytes(buffer, serialize(buffer, SendMsg_on));
}

/*************************************************************************** 
*   Function:   ArrayBuild                                                 *
*   Purpose:    Uses memcopy to transfer the struct members sequentially   *
*               into an array of char                                      *
*   Arguments:                                                             *
*   Returns:    size_t i = a count of the number of bytes in the array     *
***************************************************************************/    

size_t ArrayBuild(unsigned char *dst, const struct msg_on_send *object)
{
    size_t i = 0;

    memcpy(&dst[i], &object->descriptor_msg, sizeof object->descriptor_msg);
    i += sizeof object->descriptor_msg;

    memcpy(&dst[i], &object->address, sizeof object->address);
    i += sizeof object->address;

    memcpy(&dst[i], &object->space, sizeof object->space);
    i += sizeof object->space;

    memcpy(&dst[i], &object->cmdmsg, sizeof object->cmdmsg);
    i += sizeof object->cmdmsg;

    memcpy(&dst[i], &object->CR, sizeof object->CR);
    i += sizeof object->CR;

    memcpy(&dst[i], &object->LF, sizeof object->LF);
    i += sizeof object->LF;

    return i;
}

/*********************************************************************** 
*   Function:   USARTWrite                                             *
*   Purpose:    Writes the array data to the USART data register       *
*   Arguments:  void *object = struct member                           *
*               size_t size =  size of array remaining                 *
*   Returns:    None                                                   *
***********************************************************************/

void USARTWrite(const void *object, size_t size)        
{
    const unsigned char *byte;
    for ( byte = object; size--; ++byte )
    {
        printf(%02X, *byte);
    }
    putchar('\n');
}

Da jeg fikk denne koden, vet jeg ikke helt forstår hvordan det fungerer. Jeg kan se at memcpy tar hvert element i struct og gjør det til en seriell strøm indeksert av 'i' variabel, men jeg vet ikke hvordan USARTWrite funksjon packetises dette til en streng, eller hvordan du legger matrisen med min struct initialisering.

Beklager dette innlegget er litt lang, men jeg bare starte dette programmerings lerke, og prøver å få hodet mitt rundt dette konseptet.

Takk Dave

REDIGERE:

wow, mange gode svar raskt - takk folkens.

slaz: Det virker logisk for meg, hadde jeg egentlig ikke tenkt på at tilnærmingen som jeg ikke har virkelig fått hodet mitt rundt pekere ennå, men jeg begynner å se at de er en viktig del av C, så jeg behørig vil ha et blikk.

  • Dette kodelinje sender dataene til min UART, hva ville jeg erstatte matrisen som inneholder meldingsinnholdet med? Det virker som jeg mangler et logisk skritt her hvor jeg har en variabel som forteller meg hvor mine struktur starter og hvor stort det er, men ingen rekke å sende

    USART_SendData(USART1, message_on_contents[array_count]);
    

Harper Shelby: Takk for den beskrivelsen, det gjør det mye tydeligere i mitt sinn.

rgds

Dave

Publisert på 27/01/2009 klokken 17:29
kilden bruker
På andre språk...                            


6 svar

stemmer
6

Beklager, jeg fikk ikke se din kommentar til akkurat nå. Koden under kompilerer på Linux helt fint, så jeg håper det fungerer for deg.
printf () skriver i hex, vil du få 2 tegn for hver byte.

#include <stdio.h>

struct msg_on_send
{
char descriptor_msg[5];
int  address;
char space;
char cmdmsg[5];
char CR; 
char LF; 
};

void USARTWrite(const void *object, size_t size)    
{
    const unsigned char *byte;
      for ( byte = object; size--; ++byte )                                     
      {   
          printf("%02X", *byte);
      }   
      putchar('\n');
}

int main (int argc, char**argv)
{
    struct msg_on_send myMsg;
    unsigned char* ptr= (unsigned char*)&myMsg;

    USARTWrite(ptr, sizeof(myMsg));

    return 0;
}

Jeg håper dette hjelper.

~
~

Svarte 28/01/2009 kl. 22:50
kilden bruker

stemmer
6

Du trenger ikke å faktisk kopiere struct inn i en rekke bytes. Du kan eventuelt gjøre dette:

struct msg_on_send myMessage;

// code to set myMessage to whatever values...

// get a byte pointer that points to the beginning of the struct    
uint8_t *bytePtr = (uint8_t*)&myMessage;

// pass that into the write function, and it will write the amount of bytes passed in
USARTWrite(bytePtr, sizeof(myMessage));

Kraften av pekere! :)

Svarte 27/01/2009 kl. 18:13
kilden bruker

stemmer
1

Hvis jeg ønsker å behandle en struktur som en rekke bytes Jeg bruker vanligvis en union på kombinerte konstruksjonen med en byte array. For eksempel:

typedef union
{
    struct
    { 
        char descriptor_msg[5]; 
        int  address; 
        char space; 
        char cmdmsg[5]; 
        char CR; 
        char LF; 
    };
    BYTE bytes[];
} msg_on_send;
Svarte 08/02/2010 kl. 18:56
kilden bruker

stemmer
0

Full komplett eksempel. Perfekt fungerer. Testet i henhold til X-CODE 9 Objective-C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Person
{
    char name[20];
    int age;
};

int main()
{
    //structure variable declaratio with initialisation
    struct Person person={"Deniss Ritchie", 60};
    //declare character buffer (byte array)
    unsigned char *buffer=(char*)malloc(sizeof(person));
    int i;

    //copying....
    memcpy(buffer,(const unsigned char*)&person,sizeof(person));

    //printing..
    printf("Copied byte array is:\n");
    for(i=0;i<sizeof(person);i++)
        printf("%02X ",buffer[i]);
    printf("\n");

    //freeing memory..
    free(buffer);
    return 0;
}

Produksjon:

Copied byte array is:
44 65 6E 69 73 73 20 52 69 74 63 68 69 65 00 00 00 00 00 00 3C 00 00 00
Svarte 27/03/2018 kl. 11:18
kilden bruker

stemmer
0

Det er ganske enkelt: 1. ArrayBuild tar en peker til en msg_on_send struktur, og for hvert medlem i det, bruker memcpy kopiere bytes i en char array som ble vedtatt i like så -

char byteArray[17]; // This assumes 4-byte ints
                    // be careful though, the length *must* be long enough, or 
                    // Bad Things will happen
size_t msgSize; // Holds the size of the message built by ArrayBuild,
                // passed to USARTWrite
struct msg_on_send myMessage;
// Code to fill up myMessage appropriately

msgSize = ArrayBuild(byteArray, &myMessage); // need the & to pass a pointer as required

USARTWrite(myMessage, msgSize);

USARTWrite er bare gitt en char matrise og en størrelse - det griper hver røye i tur og skriver den til skjermen som en heksadesimal verdi med printf ().

Den 'magiske' er i ArrayBuild - memcpy gjør en bokstavelig kopi av bytes fra kilde til destinasjon, med ingen oversettelse. Forutsatt 4-byte ints, vil matrisen bygget av funksjonen se ut slik:

                     1 1 1 1 1 1 1 
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
|   A     |   B   |C|    D    |E|F|

A = descriptor_msg (char[5])
B = address (int)
C = space (char)
D = cmdmsg (char[5])
E = CR (char)
F = LF (char)

Jeg vil anta at i den 'ekte' søknad, printf () kaller ville bli erstattet av et anrop til en seriell port skrive.

Svarte 27/01/2009 kl. 17:50
kilden bruker

stemmer
0

Din structher er bare rekke bytes, inneholder det ingen pekere som peker ut av det.

Medlem-til-medlem kopien er mest sannsynlig utført for å takle justering, som (char*) &addresstrolig vil være større enn ((char*) &descriptor_msg) + 5.

USARTWritesender HEXkoder i byte av din struct til stdout, men forkaster justering. Kompilere denne koden med ulike justerings strategier vil føre til forskjellige utganger.

Omgi struktur erklæring inn #pragma pack(push, n)og #pragma pack(pop)tvinge justering, og bare kopiere strukturen byte-til-byte.

Svarte 27/01/2009 kl. 17:44
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more