2013-01-05 31 views
1
ip=ntohl(*(uint32_t*)PQgetvalue(result, i, 0)); 

此代碼段的含義是什麼?ntohl(*(uint32_t *)...)做什麼?

我的猜測是,這個代碼需要輸入從PostgreSQL數據庫(它的類型是uint32_t),並將其轉換爲IP格式(例如:192.168.x.x

是我的猜想是否正確?如果不是,那是什麼意思?

注:根據http://linux.die.net/man/3/ntohl

ntohl()函數將無符號整數,從網絡字節順序爲主機字節順序netlong。

另外,有人可以解釋什麼*(uint32_t*)做什麼?

回答

3

根據文檔:

For most queries, the value returned by PQgetvalue is a null-terminated ASCII 
string representation of the attribute value. But if PQbinaryTuples() is TRUE, 
the value returned by PQgetvalue is the binary representation of the type 
in the internal format of the backend server 

我猜PQbinaryTuples是真的那裏。

PQGetvalue()根據文檔返回char *(uint32_t *)將把那個char *變成一個指向一個unsinged的32位整數的指針,*在這之前將取消這個參數來得到實際值(一個無符號的32位整數),最後ntohl會將它轉換成平臺的本地32位整數,這大概意味着原始存儲格式是網絡順序。

如果我們將「分裂」的代碼,將給予:

// Get value from database as a char * 
char *in_database = PQgetvalue(result, i, 0); 
// Convert the pointer to char to a pointer to an unsigned, 32bit integer 
uint32_t *ptr = (uint32_t *) in_database; 
// Dereference that pointer to obtain the actually stored value 
uint32_t stored_value = *ptr; 
// Turn that value to a native integer for the CPU 
uint32_t ip = ntohl(stored_value); 
+0

確實**意味着原始存儲格式是網絡順序**意味着像x.x.x.x這樣的類型? – smttsp

+0

不,這意味着這個整數的原始存儲是大端。例如,IP「1.2.3.4」的編號爲「0x01020304」,在大端編碼中存儲爲「0x01,0x02,0x03,0x04」。但是,如果你的CPU架構是小端,這個相同的數字被「存儲」爲「0x04,0x03,0x02,0x01」。 'ntoh *()/ hton *()'函數系列可以將主機本身理解的東西和網絡需要的東西進行來回轉換。在大端CPU體系結構上,這些功能基本上都是noops,但在小端架構上卻不是這樣。 – fge

+0

@tusherity請參閱編輯以獲取更完整的說明 – fge

4

ntohl的意思是「網絡到主機長」。它(大概)將整數類型從網絡(big-endian)轉換爲主機字節排序。使用此方法時要小心,但是,如果您不熟悉機器的永久性。如果你有一個little-endian機器,並且對已經處於little-endian格式的數據使用ntohl(即沒有用big-endian或其他方式發送),你可能會遇到問題。

*(unit32_t*)是轉換爲32位無符號整數指針((unit32_t*)部分),然後前*是該指針上的解引用運算符。

編輯

這裏是字節順序一個很好的參考,如下面由NJR評論中指出:http://en.wikipedia.org/wiki/Endianness

+4

的'NTOH *'和'hton *'功能的一點是,你並不需要關心主機字節。 –

+0

'ntohl'轉換爲機器的字節序,而不是小端。你需要擔心的是你得到的東西的排序,而不是你自己的機器。 – Mat

+0

如果主機還使用大端排序,該怎麼辦? –