簡體   English   中英

C++ 獲取非靜態函數的地址

[英]C++ Get address for non-static function

例如,在 C 中,我可以通過以下方式獲取函數地址

uint64_t ptr = (uint64_t)&MyFunction;

但是在 C++ 中,我收到以下錯誤“無效的類型轉換”

uint64_t ptr = (uint64_t)&MyClass::MyFunction;

如何獲取 C++ 非靜態函數的地址?

任何幫助將不勝感激

編輯:
我需要得到這個地址請看這張圖片

class MyClass
{
public:
    void MyFunction()
    {
    
    }
};

void MyFunction()
{

}

int main()
{
    uintptr_t ptr1 = (uintptr_t)&MyFunction;
    uintptr_t ptr2 = (uintptr_t)&MyClass::MyFunction; // invalid type conversion

    return 0;
}

C++ 獲取非靜態函數的地址

您可以使用 addressof 運算符獲取非靜態成員函數的“地址”。 您獲得的地址將是“指向成員函數的指針”類型(盡管名稱不同,但不是指針)。 您不能將該指向成員函數的指針轉換為整數。


例如,在 C 中,我可以通過以下方式獲取函數地址

uint64_t ptr = (uint64_t)&MyFunction;

您可以在 C++ 中實現相同的效果,盡管不是直接在所有系統上也不是在所有系統上(“不在所有系統上”也適用於 C;您的 C 示例不適用於所有系統)。 並且只能為自由函數或靜態成員函數實現。

在 C++ 中,函數指針不能直接轉換為整數。 只有對象指針可以。 如果語言實現支持,則允許將函數指針轉換為指向空的指針(這是一個對象指針)。 因此,以下對此類支持系統有效:

using Fun = decltype(MyFunction); // not a non-static member function
Fun* function_ptr = &MyFunction;
void* void_ptr = reinterpret_cast<void*>(function_ptr)
std::uintptr_t int_ptr = reinterpret_cast<std::uintptr_t>(void_ptr);

void* void_ptr_back = reinterpret_cast<void*>(int_ptr);
Fun* function_ptr_back = reinterpret_cast<Fun*>(void_ptr_back);
assert(function_ptr == function_ptr_back);

如果系統不支持函數指針和void*之間的這種轉換,則該程序是安全格式錯誤的。

請注意,這僅適用於函數指針,不適用於成員函數指針。 如果MyClass::MyFunction是非靜態成員函數(編輯:它在您編輯的問題中),則沒有將其轉換為整數的標准方法。

PS 將對象指針重新解釋為std::uint64_t保證僅適用於迭代器可以表示所有指針值的系統。 目前可能是這樣,但為了將來的可移植性,建議使用std::uintptr_t

通常, 指向成員函數的指針與指向函數的普通指針的大小不同。 需要對虛函數ID進行編碼,除底層成員函數地址外還包含幾個字段,具體取決於情況的復雜程度(多繼承、虛基類等)

因此,您不能將其強制轉換為指向函數的指針。 就算你做了,你會怎么稱呼它? 與非成員函數不同,您需要為其提供隱藏的this參數。

某些特定成員函數的地址甚至可能沒有用; 如果它是一個虛函數,那么實際調用的函數取決於調用它的對象的類型。 因此,它需要對虛擬功能 ID 進行編碼。

只要看看sizeof指向一個成員函數,比sizeof純函數或void* 此外,您可能會發現編譯器參數控制指向成員的指針是以該類可能的最簡單方式(要求它是完整類型)編碼還是始終使用最通用的形式。

我相信您可能遇到的問題是范圍問題或大小問題。 確保您要查找的函數地址在正確的范圍內。 確定這一點后,您可以使用簡單的指針來使用指針定位內存中的函數地址。 C++ 依賴於機器處理器的底層大小來確定地址大小。 因此,不要使用 uint64_t 來收集可能不適合該大小的指針。

下面是一些在 C/C++ 中打印函數地址的簡單代碼:

#include<stdio.h>
  
void MyFunction()
{
    printf("This is My Function!");
}
  
int main(void)
{
    printf("Main address:%p\n", main);
    printf("MyFunction address : %p\n", funct);
    return 0;
}

注意: cout 也可以用於此目的。

我希望這有幫助! 如果沒有,請發表評論以進一步解釋或如何更有幫助!

我能夠得到指針

 auto _ptr = &MyClass::MyFunction;
 uintptr_t ptr = *((uintptr_t*)&_ptr);

感謝幫助

暫無
暫無

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

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