2013-02-19 94 views
3

在某些情況下,我想安排一個定製工具(struct timer_list),該工具適用於自定義數據。這種結構的function字段保存時將觸發的實際功能,如下定義:如何將自定義參數傳遞給linux定時器的函數?

void (*function)(unsigned long); 

的事情是我想傳遞一個指針,而不是unsigned long。我知道,根據體系結構,int-ptr轉換可能是安全的,也可能不安全,但我無法找到所有體系結構是否與指針對齊,因此這是我的問題(實際上是一個二合一的) :

執行longvoid*轉換是否安全?如果不是,我應該如何處理unsigned long參數來獲取我想要的定時器函數中的數據指針?

+0

我不會那樣做。必須有一個參數是unsigned long類型的原因。有沒有可用於此的聯機幫助頁? – 2013-02-19 09:25:54

+0

@ bash.d在'add_timer'和朋友的手冊頁中唯一的註釋是該參數將用於區分執行相同功能的定時器。沒有什麼關於它的 – Rerito 2013-02-19 09:37:58

+0

好吧,然後嘗試與約阿希姆的建議。我根本不會投! – 2013-02-19 09:41:09

回答

2

您可以使用傳遞的數字作爲包含您的自定義數據結構的數組的索引。

+0

我從你的回答推斷,唯一的約束'長'是它必須至少32位寬,並投射指針是不安全的,我說得對嗎? – Rerito 2013-02-19 09:36:23

+1

@Rerito正確,指向/來自指針的類型轉換並不安全,並且大小可能不同。 – 2013-02-19 09:40:52

+0

所以看來,唯一的解決方案將是有一些全局變量存儲(長,數據)夫婦。就像你所建議的數組或者任何動態結構(我想用「long」鍵索引的樹)。無論如何,答案接受! – Rerito 2013-02-19 09:47:15

4

在定時器功能,並且在一些其他情況下,它能夠到只投的指針數據結構來unsigned long,將其存儲在struct timer_listdata領域和投下的定時器功能的參數回到指向你的數據結構的指針。這似乎是一種常見的做法。第7章對此事

Linux Driver Development, 3rd. ed.狀態如下:

如果您需要在參數中傳遞多個項目,你可以捆綁它們作爲一個單一的數據結構,並通過指針轉換爲unsigned long,在所有支持的體系結構上都是安全的做法,並且在內存管理中很常見(如第15章所討論的)。

在內核中有很多這樣的例子,例如見ext4文件系統模塊中的s_err_report timer。如上所述,指向struct super_block的指針被傳遞給定時器函數,並轉換爲unsigned long並返回。

+0

有教育意義的答案。在從內核中查看現有示例之後,有些東西讓我感到震驚:在指針分配中沒有周圍的'#ifdef'。因此,如果'long'不足以安全地轉換指針,那麼稍後會導致未定義的行爲(最壞情況),或者如果 - 設置了錯誤(最好),則會阻止編譯。不強制執行此大小對齊的體系結構因此無法獲得可靠的ext4支持? – Rerito 2013-02-19 15:43:46

+1

如果我沒有弄錯,對於內核支持的每種體系結構,對於在內核模式下運行的代碼,「sizeof(unsigned long)」與sizeof(void *)'相同。用戶模式應用程序是另一回事,不同的規則可能適用於此。在前面引用的「Linux驅動程序開發」一書的第11章中,有十幾種體系結構的各種數據類型的大小比較有趣。 – Eugene 2013-02-19 18:11:04

+1

另外引用第11章明確指出。 「因此,內核中的通用內存地址通常是無符號的,這意味着指針和長整型的大小始終相同,至少在Linux所支持的所有平臺上。」 – Eugene 2013-02-19 18:15:41

相關問題