[英]Use a void* argument to pass integer OR a pointer
我想檢測 void* 類型輸入 function 參數的值是 integer 還是指針。 目前,我只通過 integer (這是午夜指揮官源):
mc_event_raise (MCEVENT_GROUP_CORE,
"clipboard_file_from_ext_clip",
(void*)(intptr_t)clip_id);
但是我有時也想在同一參數中傳遞一個字符串(char *),因為擴展 API 會很困難。 我知道這是錯誤的,但是,也許有一種完全合法的方式來獲得這種效果? 我的想法: – 地址通常與 4 或 8 個字節對齊,所以我可以從 clip_id 中跳過這些值(跳過它們)然后解碼這些值? if (data % 8) then clip_id = decode_clip_id(data);
? – 也許指針不能小到 10…20,一個簡單的檢查就足夠了? – 其他想法……?
像這樣的問題可以通過包含聯合和標簽的結構來解決。
struct EventData {
enum { EV_IS_INT, EV_IS_PTR } type;
union {
intptr_t v_int;
void * v_ptr;
};
};
因此,您可以傳遞一個指向此EventData
的指針,回調可以根據type
的值解碼是訪問v_int
還是v_ptr
。
struct EventData *ed = makeEventData (EV_IS_INT, clip_id);
mc_event_raise (MCEVENT_GROUP_CORE,
"clipboard_file_from_ext_clip",
ed);
如果事件異步完成,您可能需要動態創建事件,然后回調 function 必須在使用參數完成回調時釋放 memory。
Windows 用他們的 HANDLE 和資源 ID 做了很多這樣的黑客行為。
您的 integer 需要具有定義的有效范圍。 超出該范圍的任何內容都可能是指針。
幾乎所有操作系統都保留低 memory 區域。 您可能可以假設 0 到 65535 的 16 位范圍不是指針。 除此之外變得不確定。
如果您的代碼需要可移植到嵌入式 RTOS 或獨立環境之類的東西,那么您不能假設任何關於指針的事情。
在任何情況下,您可能都需要某種 function 來創建要傳遞到您的 void* 的值,這將有一個assert
或abort
以避免意外創建無效值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.