0
点赞
收藏
分享

微信扫一扫

C++ CONTAINING_RECORD 宏操作技巧学习

Gaaidou 2022-01-21 阅读 46

CONTAINING_RECORD
Containing record是一个在C++编程中用处很大的一种技巧,它的功能为已知结构体或类的某一成员、对象中该成员的地址以及这一结构体名或类名,从而得到该对象的基地址。

VC6新建一个单文档工程;在视类CPP文件头部添加一个结构体;


 

先输出一下m_2的相对地址;

void CContainView::OnDraw(CDC* pDC)
{
	CContainDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CString str1;
	int* v3 = (int*)(&((PMYDATA)0)->m_2);
	str1.Format("%p",v3);
    //printf("%p\r\n",v3);
	pDC->TextOut(50, 50, str1);
}

 

如果是用 %d 格式化,则输出如下;

 

%p 我还没用过;

资料中的格式化符有,

Format用于转换的格式字符:
  %c                 单个字符
  %d                 十进制整数(int)
  %ld                十进制整数(long)
  %f                 十进制浮点数(float)
  %lf                十进制浮点数(double)
  %o                 八进制数
  %s                 字符串
  %u                 无符号十进制数
  %x                 十六进制数
 

然后来使用 CONTAINING_RECORD 宏;加在视类CPP文件的头部;

 

void CContainView::OnDraw(CDC* pDC)
{
	CContainDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CString str1;
	MYDATA mydata = {333,222,111};
    int* v1 = &mydata.m_2;
    PMYDATA v2 = CONTAINING_RECORD(v1, MYDATA, m_2);
    //printf("%d %d %d\n", v2->m_1,v2->m_2,v2->m_3);
	str1.Format("%d  %d  %d", v2->m_1,v2->m_2,v2->m_3);
	pDC->TextOut(50, 50, str1);
}

由m_2获得v2,v2就是对象的地址;然后用v2来输出各个成员;如下; 

 

在ReactOS源码分析,内核对象分析时,也会用到这一技巧;

 

 

举报

相关推荐

0 条评论