2013-02-22 54 views
1

我有一個函數UartSend()通過UART發送數據到網絡。它需要的參數無符號的字符和一個整數轉換C結構爲無符號字符

UartSend(unsigned char *psend_data,int length); 

我想通過這個功能

#pragma pack(push, 1) 
struct packet 
{ 

    int a; 
    char b[3]; 
    ... 

}PacketData; 

#pragma pack(pop) 

發送結構如何隱蔽這種結構爲unsigned char通過UartSend發送這些數據? 感謝..

+1

你嘗試只是鑄造'packet'到'無符號字符*'?它可能會在你的情況下有對齊問題.. – 2013-02-22 07:35:21

+5

決定你想要的數據格式。這被稱爲*協議*。在你的情況下,你可能想要將數據作爲32位或64位的大端整數發送,然後是三個字符。你將「建立」這個數據到一個緩衝區,然後發送它。客戶端將收到此信息,然後從數據中重建原始結構。發送直播可能會引入大量的對齊和打包問題,這些問題實際上是您想要避免的,特別是如果客戶端可以運行不同的平臺或與發送方具有不同的內存架構。 – WhozCraig 2013-02-22 07:41:44

回答

5

你可以簡單地轉換爲unsigned char *,只要你得到你的尺寸正確:

PacketData pkt; 
UartSend((unsigned char *)&pkt, sizeof(pkt)); 

unsigned char *在這方面真的只是意味着字節。

當然,在連接的另一端,您需要合併程序邏輯重新編譯爲PacketData(或某些類似的結構)。

編輯:但是,請注意,@WhozCraig指出了評論,如果你的目標平臺是不完全相同的源平臺,你需要考慮對齊的問題(或者,依靠GNU擴展像__packed__

+0

這很簡單的錯誤。我忘了和鑄造...... – Shihab 2013-02-23 04:12:38

0

您可以使用聯合以結構或無符號字符數組的形式訪問數據。 這樣可以避免使用直接投射獲得的混疊問題。

0

Structures can have extra bytes in them to make each element aligned。這些額外的字節可以根據使用的編譯器/平臺而有所不同。因此,你想要做的事情可能是不可能的。

我建議你寫一個函數來做jo。它需要將每個元素從結構中拉出並單獨發送。第二個函數需要接收這些值,並將它們存儲回函數中。

請記住,endianism也可能是一個問題,並使用network byte ordering functions來確保整數值以標準格式發送。如果系統是不同的類型,浮點值可能需要某種額外的轉換步驟。

0

TIPS

  1. 字節對齊/包之一。建議使用自然字節對齊方式,以獲得最佳性能。 SUN和AIX'自然字節對齊'敏感。
  2. 字節序列轉換,通常情況下,發送者用big-endian發送,接收者將BYTES轉換爲本地端。小(WINDOWS,LINUX)/大(AIX,SUN,HP)
0

你的數據結構對齊,使您的INT落在單詞boundries,這對於你的目標可能是32或64位。

您可以重新組織像這樣的結構,使這不會發生: 結構thestruct

{ 
int var6; 
unsigned char var1; 
unsigned char var2; 
unsigned char var3[2]; 
unsigned char var4; 
unsigned char var5[8]; 
unsigned char var7[4]; 
};