文章目录
- 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");
}