[英]Converting a member function to a static function in C++
我正在編寫一個內存測試框架,在其中我用自己的內存替換動態內存分配函數(例如,malloc,realloc,free等)。 但是,系統需要靜態函數(我不能改變它)。
我有一個MemoryTester類,它記錄內存調用,我想綁定其內存分配函數的成員函數實現。 這可能用C ++嗎?
編輯:
這是一些突出我正在嘗試做的代碼:
typedef void*(allocateFuncPtr) (uint8_t);
typedef void (freeFuncPtr) (void*);
void setAllocateFunction(allocateFuncPtr) {...}
void setFreeFunction(freeFuncPtr) {...}
class MemoryTester
{
void *malloc(uint8_t size);
void free(void *ptr);
}
int main()
{
MemoryTester *tester = new MemoryTester();
//want to set allocate and free functions to those in tester
setAllocateFunction( tester->getAllocateFunction() );
setFreeFunction( tester->getFreeFunction() );
return 0;
}
編輯后,我的意圖似乎更清楚了。 您可以做的最簡單的事情是在MemoryTester
使用靜態成員函數而不是非靜態成員函數。 如果他們需要保持狀態,則必須將該狀態移動為該類的static
成員。
如果您的編譯器支持0x lambdas,則可以使用閉包:
int main() {
MemoryTester tester; // If no need for dynamic allocation, don't use it.
setAllocateFunction([&tester](uint8_t size) { return tester.malloc(size); });
setFreeFunction([&tester](void *p) { tester.free(p); });
return 0;
}
您的MemoryTester類不需要更改,也不需要setAllocateFunction和setFreeFunction所屬的庫。
如果沒有lambda,而不是單例類 ,請使用單個全局對象:
struct MemoryTester {
void* malloc(uint8_t size); // Neither are static.
void free(void *p);
};
MemoryTester tester_a;
void* tester_a_malloc(uint8_t size) { return tester_a.malloc(size); }
void tester_a_free(void *p) { return tester_a.free(p); }
int main() {
setAllocateFunction(&tester_a_malloc);
setFreeFunction(&tester_a_free);
}
這里的優點是整個MemoryTester類沒有因為它的特殊需要而受到限制 。 您可以根據需要創建更多功能(例如tester_b_malloc / free)以適應同一程序中的其他用途。
如果您正在使用GCC,那么您可以讓鏈接器使用--wrap選項(或-Wl, - wrap,malloc)為您包裝該函數。
然后你可以攔截對malloc的調用,因為對該函數的所有調用都將被重定向到__wrap_malloc。 你可以使用名稱__real_malloc來調用真實的(原始c-lib)malloc函數,或者你可以替換你自己的替換(如果沒有調用__real_malloc,那么鏈接器可能能夠刪除原來的c- lib malloc all-together)。
void *__wrap_malloc (size_t c)
{
printf ("malloc called with %zu\n", c);
return __real_malloc (c);
}
FWIW,您可以替換全局的new和delete操作,然后您可以只使用自己的內存系統(即使您使用第三方編譯庫中的代碼,只要它們沒有重載全局new和delete)。
這里有一些很棒的信息: 替換“新”和“刪除”的教程
如果我理解你的要求,就沒有“約束力”。 一旦分配了內存,就可以告訴編譯器用戶輸入一個類型,在你的情況下是一個reinterpret_cast。 例如,在你的分配函數中:
unsigned char* raw_memory = allocation( std::size_t );
MyFinalType* object = reinterpret_cast<MyFinalType*>(raw_memory); // tells the compiler to take this memory as a MyFinalType.
然后你返回你的最終類型。
要知道要使用的類型,您肯定想要使用模板。
不要忘記C ++是一種靜態類型語言:您不能將函數綁定到對象類型。 好的,你可以,但是,你必須使用std :: function或函數指針,這不是你想要的。
除非您創建一個全局對象。 如果框架采用常規函數指針,那么你就會堅持使用它提供的內容,如果它沒有提供傳統的void * userdata樣式,那么你就會被填充,或者它是全局對象時間。
擁有一個單獨的MemoryTester對象,並具有調用該對象的成員函數的橋接靜態函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.