うにコピー structメンバのバイト配列のc
-
20-08-2019 - |
質問
テーマとしてコピーの構造体を含む混合物をint、charの配列の文字数バイト配列に送信するシリアルライン。していきたいと思い
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');
}
って得られたこのコードから完全に理解いただけます。参照:うにmemcpy間の各要素に、構造体と、シリアルストリーム指の'i'変数がわからないのにUSARTWrite機能packetisesその文字列る方法については、荷重の配列と構造体トの再計算.
ありが少し長くしていると思うから本プログラミングひばりることができるように私の頭部周辺のこのコンセプト。
感謝 Dave
編集:
なんと、多くの回答が多く感謝しまいました。
slaz:と思われる論理的思ってんのか考えるアプローチといった私の頭の周りのポインタしかし、私は、こうした開始されていて、とても重要な役割を果のC、正しています。
このコードデータを送信し私のUARTは、何ように交換する配列を含むメッセージの内容に。そうでない欠論理的な一歩がここにしたいことが分かった変数聞かせていただきまして私の構造が開始できないが、配列を送信
USART_SendData(USART1, message_on_contents[array_count]);
ハーパーシェルビ:それはそれはありがとうございまdescriptionでより鮮明に見せなければならない興味を持っていました。
ペ
Dave
解決
申し訳ありませんが、私は今まで、あなたのコメントを見ていません。
以下のコードは、Linux上でうまくコンパイルので、私はそれがあなたのために働く願っています。
printf()は六角で印刷され、あなたがバイトごとに2つの文字を取得します。
#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;
}
私はこのことができます願っています。
〜
〜
他のヒント
あなたが実際にバイト配列に構造体をコピーする必要はありません。 あなたは、必要に応じてこれを行うことができます:
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));
ポインタのパワー! :)
私は通常、バイト配列と組み合わせた構造に組合を使用したバイト配列のような構造を扱いたい場合。たとえばます:
typedef union
{
struct
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
BYTE bytes[];
} msg_on_send;
あなたはstruct
ここでバイトの配列だけがある、それはそれを指摘して何のポインタが含まれていません。
メンバーツー部材コピーが最も可能性が高い(char*) &address
はおそらく((char*) &descriptor_msg) + 5
よりも大きくなるように、アラインメントに対処するために行われる。
USARTWrite
HEX
ためにあなたの構造体のバイトコードをstdout
送信しますが、アライメントを破棄します。別のアライメント戦略にこのコードをコンパイルすると異なる出力につながるます。
#pragma pack(push, n)
にあなたの構造体宣言を囲み、#pragma pack(pop)
アライメントを強制的に、そしてちょうどあなたの構造バイトツーバイトをコピーします。
これはかなり簡単です: 1. ArrayBuildはmsg_on_send構造体へのポインタをとり、そこに各メンバーのために、そうのように渡されたchar配列にバイトをコピーするのmemcpyを使用する -
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は単にchar配列とサイズが与えられて - それは順番に各文字をつかみ、printf関数とのHEX値()
のように画面にそれを印刷します。「魔法」をArrayBuildである - のmemcpyは、変換せず、送信元から宛先までのバイトのリテラルコピーを行います。
:4バイトのint型と仮定すると、機能によって構築された配列は、そのようになります。 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)
私は「本当の」アプリケーションでは、printfの()の呼び出しは、シリアルポートのライトへの呼び出しに置き換えられるだろうと。
と仮定したいです完全な例。完璧に動作します。 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;
}
出力:
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