簡體   English   中英

使用 void* 參數傳遞 integer 或指針

[英]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* 的值,這將有一個assertabort以避免意外創建無效值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM