簡體   English   中英

將指向成員函數的指針轉換為intptr_t

[英]Cast pointer to member function to intptr_t

問題:有沒有辦法在C ++中將指向成員函數的指針轉換為intptr_t?

已知因素:

  1. 我知道成員函數指針非常特殊
  2. 我知道成員函數傳遞隱藏的“this”參數(__thiscall)。
  3. 我知道sizeof(成員函數指針)> sizeof(intptr_t)在某些情況下,在這個問題中,我只討論可能的情況,即在我的情況下sizeof(成員函數指針)== sizeof(intptr_t) 。
  4. 最后我知道將指針轉換為intptr_t並不是一個好的模式。

示例代碼:

class test // No inheritance, in the case I need
    {
    public:
    void func();    // No virtual, or any special modifiers in the case I need
    };

void main2()
    {
    intptr_t p = &test::func;
    };

我知道一個解決方法來做這個演員,但我不喜歡它,因為它重新出現一個臨時變量:

void my_way()
    {
    intptr_t p;
    auto t = &test::func;       // Temp variable, I don't like the fact I need to use it, but I have no other way for now
    p = *reinterpret_cast<intptr_t*>(&t);
    };

所以問題是如何將內聯技巧作為右值表達式進行內聯,沒有臨時變量(並且沒有相同的memcpy)。

例:

reinterpret_cast<??>(???_cast<??>(???_cast<??>( &test::func )))

(我不關心表達的美妙程度)。

-------------------------(下面有些為什么而不是問題的想法)-------------- ------------------

這個網站上有一些類似的主題,但是他們都主要談到“為什么你這樣做?”,或者“為什么你需要這個?”,並且談到這個問題解決了那個問題的人,但不是我。

為什么我需要這個人員:我正在編寫某種任務,我決定實現自己的動態鏈接機制。 可以有幾個特定的​​應用程序。

在我的情況下 - 動態鏈接機制 - 我想將一個指向函數的指針傳遞給另一個模塊。 我有一個類和一個接口作為一個單獨的結構(我知道,有一些libs采用相同的方法)。 已知使用此機制的所有類都是普通的(根本沒有繼承,所以沒有虛擬等)。 所有這些都運行在x86 32位,或最多64位Windows上,由MSVC 2012編譯。由於接口與類完全隔離,因此它使用指針數組。 Lib將數組傳遞給主機進程。 在主持人的過程中我有這個...它甚至不是一個“問題”,但仍然:

inline int my_interface::func_name(int param)
    {
    decltype(&interface_name::func_name) temp;
    *((intptr_t*)&temp) = reinterpret_cast<interface_name::funcs*>(interface_desc->funcs)->func_name;
    return (reinterpret_cast<decltype(this)>(object)->*temp)(param);
    };

它是一個內聯函數,所以我希望它盡可能小,如果有可能我想消除“temp”,因為我不確定編譯器是否會正確地消除它,即使是所有的優化。

其他應用程序(hypotetic): - 如果我想保護我的成員函數所在的內存頁面與特定防護,該怎么辦? WinAPI為我提供了一種方法,但它需要頁面的地址。 對於正常功能這樣做沒有問題,但是對於成員 - 僅對我描述的WA? 還是有辦法? - 如果我想在運行時修補圖像怎么辦? 即找到一些const並用另一個替換它? 運行時修補至少有幾個原因:2.1動態鏈接重定位過程,2.2代碼混淆。

這只是一個注意事項 - 讀者經常會問“為什么”,我不想討論為什么,因為在我看來可以有很多應用程序,所有這些應用程序都不適用於新手,但更多適用於安全人員......

我在這里要求不要討論“為什么這樣做?”,“為什么不使用現有的機制來實現dll / boost /其他庫/其他語言?” 在這個帖子里。

不,規范不允許您將函數指針或成員指針強制轉換為intptr_t。 這樣做的原因是因為您可能需要多個intptr_t的數據來描述它們。 例如,gcc上的成員指針是3 intptr_t的長,而MSCV的長度是1到4 intptr_t。 其中大部分用於處理虛擬功能。

在一些舊的硬件上(C ++支持),指針實際上也比函數指針小。 這種情況發生在小型系統上,您可能只需指向8位內存結構,但程序會加載到16位程序存儲空間中。

大多數情況下,您嘗試使用的這種模式用於創建委托:成員函數指針永久地綁定到特定對象。 這可以通過2個int指針和包裝函數來完成

struct Delegate
{
    intptr_t   obj;  // I'll use intptr_t here, but often this is void*
    intptr_t   func;
};

// you need one of these for each type of mfp you use
static void callT_Test(intptr_t obj)
{
    T* realObj = reinterpret_cast<T*>(obj);
    realObj->test();
}

// constructing a delegate to call test on t
Delegate d;
d.obj = reinterpret_cast<intptr_t>(&t);
d.func = &callT_Test;

暫無
暫無

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

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