versuchen, Strukturkomponenten zu kopieren in c auf Byte-Array
-
20-08-2019 - |
Frage
Ich bin versucht, die Mitglieder einer Struktur, die eine Mischung von ints, Chars und Arrays von Zeichen in einen Byte-Array zu kopieren, um eine serielle Leitung zu senden. Bisher habe ich
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');
}
Als ich diesen Code erhalten, ich verstehe nicht ganz, wie es funktioniert. Ich kann sehen, dass das Memcpy jedes Element der Struktur nimmt und macht es zu einem seriellen durch das ‚i‘ Variable indiziert Strom, aber ich weiß nicht, wie die USARTWrite Funktion diese in einen String paketiert, oder wie das Array zu laden mit meine struct Initialisierung.
Leider Dieser Beitrag ist ein bisschen lang, aber ich beginne gerade diese Programmierung Lerche, und versuche, meinen Kopf, um dieses Konzept zu erhalten.
Danke Dave
EDIT:
wow, viele gute Antworten schnell -. Danke Jungs
Slaz: Das scheint mir logisch, ich hatte nicht wirklich darüber nachgedacht, diesen Ansatz, wie ich wirklich nicht meinen Kopf noch um Zeiger bekam, aber ich fange an zu sehen, dass sie ein wesentlicher Bestandteil von C sind, so dass ich ordnungsgemäß wird einen Blick.
-
Diese Codezeile sendet die Daten an meine UART, was würde ich das Array ersetzen mit dem Nachrichteninhalt enthalten? Es scheint, als ob ich einen logischen Schritt bin hier fehlt, wo ich eine Variable haben mir zu sagen, wo meine Struktur beginnt und wie groß es ist, aber kein Array senden
USART_SendData(USART1, message_on_contents[array_count]);
Harper Shelby: Vielen Dank für diese Beschreibung, es es viel klarer in meinem Kopf macht
.rgds
Dave
Lösung
Sorry, ich habe nicht nur jetzt, bis.
Der folgende Code kompiliert unter Linux ganz gut, so dass ich hoffe, dass es für Sie arbeitet.
printf () in Hex drucken, werden Sie für jedes Byte 2 Zeichen erhalten.
#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;
}
Ich hoffe, das hilft.
~
~
Andere Tipps
Sie haben nicht wirklich die Struktur in ein Array von Bytes zu kopieren. Man könnte dies gegebenenfalls tun:
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));
Die Macht des Zeigers! :)
Wenn ich eine Struktur als ein Array von Bytes behandeln möchte ich eine Vereinigung der Regel verwenden, um kombinierte die Struktur mit einem Byte-Array. Zum Beispiel:
typedef union
{
struct
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
BYTE bytes[];
} msg_on_send;
hier Ihre struct
von Bytes nur Array ist, es enthält keine Hinweise, die davon hinweisen.
Mitglied zu Mitglied Kopie wird höchstwahrscheinlich durchgeführt mit Ausrichtung gerecht zu werden, wie (char*) &address
wahrscheinlich größer sein wird als ((char*) &descriptor_msg) + 5
.
USARTWrite
sendet HEX
Codes des Bytes Ihrer Struktur stdout
, sondern verwirft Ausrichtung. Das Kompilieren dieses Codes mit unterschiedlichen Ausrichtung Strategien zu verschiedenen Ausgängen führen.
Schliessen Sie Ihre Strukturdeklaration in #pragma pack(push, n)
und #pragma pack(pop)
Ausrichtung zu zwingen, und kopieren Sie einfach Ihre Struktur Byte-to-Byte.
Es ist ziemlich einfach: 1. ArrayBuild nimmt einen Zeiger auf eine msg_on_send Struktur und für jedes Mitglied in dort verwendet Memcpy das Bytes in ein char Array zu kopieren, die in etwa so übergeben wurde -
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 ist nur ein char-Array und eine Größe gegeben - es packt jedes Zeichen wiederum und druckt sie auf dem Bildschirm als Hex-Wert mit printf ()
.Die ‚Magie‘ ist in der ArrayBuild - Memcpy hat eine wörtliche Kopie von Bytes von der Quelle zum Ziel, ohne Übersetzung. Unter der Annahme, 4-Byte-Ints, das Array von der Funktion aufgebaut wird, wie so aussehen:
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)
ich davon ausgehen, dass würde in der ‚realen‘ Anwendung, die printf () Anruf von einem Anruf an eine serielle Schnittstelle Schreib ersetzt werden würde.
Voll vollständiges Beispiel. Perfekt funktioniert. Getestet unter 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;
}
Ausgabe:
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