文章目錄
- c++ - pointer convert - class member function's pointer <==> void*
- 概述
- 筆記
- END
c++ - pointer convert - class member function’s pointer <==> void*
概述
想將結構體中的void指針賦值為類成員函數的指針, 用于回調.
這個結構體相關的函數寫完, 就不用再因為傳入的類指針是不同的業務類, 而再去修改這個類指針的類型為 X
直接將類成員函數指針轉為void是不行的, 編譯器不支持.
試了一下, 可以將類成員函數指針的地址再轉成void**, 這樣可以. 等于是結構體中的void指針是一個2級指針.
筆記
/*!
* \file exp006_fun_pt_to_void_pt.cpp
* \note c++ - pointer convert - class member function's pointer <==> void*
*/#include "my_openSSL_lib.h"
#include <openssl/crypto.h>
#include <openssl/bio.h>#include <stdlib.h>
#include <stdio.h>
#include <assert.h>#include "CMemHookRec.h"void my_openssl_app();
void my_fn_test();class CTest
{
public:CTest(){}virtual ~CTest(){}int Add(int a, int b){return (a + b);}
};int main(int argc, char** argv)
{setvbuf(stdout, NULL, _IONBF, 0); // 清掉stdout緩存, 防止調用printf時阻塞mem_hook();my_openssl_app();mem_unhook();return 0;
}void my_openssl_app()
{// 做個實驗, 將類成員函數指針強轉為普通指針// 一切皆可強轉為普通指針typedef void(*PFN_my_fn_test)();typedef int(CTest::* PFN_Add)(int a, int b);int i = 0;// 普通函數強轉為普通指針void* p = my_fn_test;if (NULL != p){// 將普通指針轉成普通函數指針來干活PFN_my_fn_test pfn = (PFN_my_fn_test)p;pfn();}// 類成員函數強轉為普通指針CTest test;PFN_Add pClassMemberFn = &CTest::Add;// _ppVoidPt_ClassFn 也可以定義成void*, 反正是要按照2級指針來用才行.void** _ppVoidPt_ClassFn = (void**)&pClassMemberFn; // 到此, 將類成員函數指針轉為了普通指針// 此時可以將_ppVoidPt_ClassFn 傳進參數結構體中的void*成員, 這樣參數結構體中的類函數指針就可以沒有具體類型了, 不用包具體類的頭文件(避免污染參數結構體中的指針類型)// 這樣做出的結構體, 可以給任意類來用. 只要結構體中的指針用途定好了, 以后就再也不用改結構體中的指針類型.// 網上能查到的普通用法 : 用類的this指針和類成員函數指針來干活CTest* pClassThis = &test;i = (pClassThis->*pClassMemberFn)(1, 2);printf("(pClass->*pClassFn)(1, 2) = %d\n", i);// 網上能查到的普通用法 : 用類實例對象和類成員函數指針來干活i = (test.*pClassMemberFn)(2, 3);printf("(test.*pClassFn)(2, 3) = %d\n", i);// 網上未見的用法 - 將void*指針轉成類指針來干活// 其他用到類回調指針來干活時, 他這時本來就知道這個類指針具體啥類型的(因為就是他傳入的), 將void*指針強轉成類指針來用.// 可以分為2步將void*指針轉為類指針PFN_Add* ppClassFn_restore = (PFN_Add*)_ppVoidPt_ClassFn;PFN_Add pClassFn_restore = *ppClassFn_restore;i = (test.*pClassFn_restore)(3, 4);printf("(test.*pClassFn_restore)(3, 4) = %d\n", i);// 也可以1步將void*指針轉為類指針PFN_Add pClassFn_restore1 = *(PFN_Add*)_ppVoidPt_ClassFn;i = (test.*pClassFn_restore1)(4, 5);printf("(test.*pClassFn_restore1)(4, 5) = %d\n", i);/*! run resut>> my_fn_test(pClass->*pClassFn)(1, 2) = 3(test.*pClassFn)(2, 3) = 5(test.*pClassFn_restore)(3, 4) = 7(test.*pClassFn_restore1)(4, 5) = 9free map, g_mem_hook_map.size() = 0*/
}void my_fn_test()
{printf(">> my_fn_test\n");
}