質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1937閲覧

【C言語】配列から構造体へコピーしたい

hachimitu

総合スコア36

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/07/30 12:52

#やりたいこと
配列データuart_bufferを構造体にコピーするときにmemcpyを使用すると左(NG)のように、payload1に0x44332211とセットされてしまいます。
これをpayload1に0x11223344とセットしたい(右のOK)のでビットシフト処理で(下記コード)無理やり格納しました。他に良い方法があれば知りたい。
セットしたい

イメージ説明

C言語

1 /*パソコンデータ受信用構造体にデータセット*/ 2 //memcpy(&Pc_to_mst_data_frame_struct.slv_id, UART_struct->uart_buffer,size); 3 Pc_to_mst_data_frame_struct.slv_id = UART_struct->uart_buffer[0]; 4 Pc_to_mst_data_frame_struct.command_id = UART_struct->uart_buffer[1]; 5 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[2] << 24; 6 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[3] << 16; 7 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[4] << 8; 8 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[5]; 9 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[6] << 24; 10 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[7] << 16; 11 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[8] << 8; 12 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[9];

#しりたいこと
上記コード以外でスマートなやり方があればご教示お願いします。
無知で申し訳ありません。宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2019/07/30 13:23

structの定義を書いてください。
hachimitu

2019/07/30 13:40

情報不足で申し訳ありません。 こちらになります↓ typedef struct Pc_to_mst_data_frame_handle_typedef { uint8_t slv_id; uint8_t data_size; uint8_t command_id; int32_t payload1; int32_t payload2; int32_t payload3; int32_t payload4; }__PACKED Pc_to_mst_data_frame_handle_typedef;
rubato6809

2019/07/30 14:11

その構造体定義をここに返答するのではなく、質問を編集して書き加えてくださいな。
guest

回答3

0

データ側を変更出来ないのであれば
ntohlを使う事になります


追記

あくまでも、ビッグエンディアン(ネットワークバイトオーダー)からホストバイトオーダーへの変換であることに留意が必要

c

1// MSVCの場合、以下どちらか 2#include <winsock2.h> 3#include <winsock.h> 4 5// Linuxの場合、以下どちらか 6#include <netinet/in.h> 7#include <arpa/inet.h> 8 9memcpy(&Pc_to_mst_data_frame_struct.slv_id, UART_struct->uart_buffer,size); 10Pc_to_mst_data_frame_struct.payload1 = ntohl(Pc_to_mst_data_frame_struct.payload1);

投稿2019/07/30 13:16

編集2019/07/31 01:14
asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

多分、その方法が妥当だと思います。
少し、気になったのは、

C

1 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[2] << 24; 2 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[3] << 16; 3 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[4] << 8; 4 Pc_to_mst_data_frame_struct.payload1 |= UART_struct->uart_buffer[5]; 5 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[6] << 24; 6 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[7] << 16; 7 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[8] << 8; 8 Pc_to_mst_data_frame_struct.payload2 |= UART_struct->uart_buffer[9];

でのコピー順。UART_struct->uart_buffer[5] からの逆順とし、最初は、|= での OR演算でなく、単なる = での代入としましょう。(ゼロクリアされてない) 他の payload? も同様ですね。

また、memcpy()で失敗したとありますが、データサイズは一致してますか?
Pc_to_mst_data_frame_handle_typedefは、 unit8_t が 3つでその後、int32_t ちょっと違うように見えます。
また、この手のコピーは、unionが定番とも思いましたが、payload1 が奇数アドレス。ここ、偶数するのが一般的と思いました。(従って unionは使えない)

投稿2019/07/30 14:48

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hachimitu

2019/08/05 12:44

回答ありがとうございます。指摘されたところは修正しました。助かりました。
guest

0

通信データは数値の並び順が決まっているため、memcpyでコピーしてしまうと逆順になってしまいます
こういう場合は数値取得のためのマクロを定義しておきます

C

1// 16bit数値の取得 2#define GETWORD(p) (((uint8_t*)(p))[0]<<8 | ((uint8_t*)(p))[1]) 3// 32bit数値の取得 4#define GETDWORD(p) (GETWORD(p)<<16 | GETWORD(((uint16_t*)(p))+1)) 5 6 7... 8 Pc_to_mst_data_frame_struct.payload1 =GETDWORD(& UART_struct->uart_buffer[2]); 9

プログラマたるもの、いかに手を抜くかを考えましょう

投稿2019/07/30 14:38

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問