传递类成员函数指针导致 Run-Time Check Failure #0 错误与 C4121 结构体对齐警告

笔者希望传递某个类的函数指针,以做回掉用,如下:

class CClass; typedef void ( CClass::* PFNCALLBACK )( void );

首先说明的是,在 typedef 这个 PFNCALLBACK 的之前,并没有 #include CClass.h 文件,而是使用了向前声明方式告诉编译器我有一个 CClass 类,随后定义一个类似下面的结构体:

struct CALLBACKINFO { CClass * obj; PFNCALLBACK pfn; __int64 u1; __int64 u2; // ...
};

随后创建了一个设置回掉函数的函数,如下:

void setCallBack( CClass * _obj, PFNCALLBACK _pfn ){ CALLBACKINFO ci = { 0 }; ci.obj = _obj; ci.pfn = _pfn; // ...
}

编译的时候给了我 C4121 警告,说什么【封装要区分成员的对齐方式】,用了 pack( 1 )、pack( 2 )、pack( 4 )、pack( 8 ) 都没能消除这个警告,心想这只是警告,就暂且无视它吧,结果每次 setCallBack( ) 函数调用完毕并且跳出调用者代码块之后,马上触发 Run-Time Check Failure #0 错误,网上查资料,很多人说是尝试把两种不同调用约定的函数指针进行赋值导致错误,但是我在 PFNCALLBACK 前面放上 __thiscall 后,错误依旧,只好把苗头指向结构体对齐上;

初步猜测可能是在创建 CALLBACKINFO 结构体的时候编译器缺少一些必须的 CClass 信息,导致警告,在 typedef 之前 #include 上 CClass.h 文件,警告和错误都消失了;

问题是消失了,只是这种解决方法是否能从根本上解决问题,还不得知,希望各位前辈指点一下;

 

--------------------------------------------------------------------------------------------------------------------

下面补充一下情况描述,刚才重新创建了一个工程,把问题模拟了出来,一共有五个文件,分别是 cft.h、cft.cpp、csm.h、csm.cpp 以及 main.cpp,工程设置了 Level 4 警告级别,不然编译器就是不吱声(汗),五个文件的内容如下:

// cft.h
 #ifndef CFT_H #define CFT_H

class CCFT { public: virtual void callBack( void ); }; #endif
// cft.cpp
 #include "cft.h"

void CCFT::callBack( void ){ }
// csm.h

#ifndef CSM_H
#define CSM_H #include <list>


class CCFT; typedef void ( CCFT::* PFNCALLBACK )( void ); struct CALLBACKINFO { CCFT * obj; PFNCALLBACK pfn; __int64 u1; }; class CCSM { public: void addCallBack( CCFT * _obj, PFNCALLBACK _pfn ); private: std::list< CALLBACKINFO > cb_list; }; #endif
// csm.cpp
 #include "csm.h"

void CCSM::addCallBack( CCFT * _obj, PFNCALLBACK _pfn ){ CALLBACKINFO ci = { 0 }; ci.obj = _obj; ci.pfn = _pfn; cb_list.push_back( ci ); }
// main.cpp
 #include "cft.h" #include "csm.h" CCSM csm; class CClass : public CCFT { public: void startup( void ){ csm.addCallBack(this, ( PFNCALLBACK ) & CClass::callBack ); } void callBack( void ){ } }; int main( int argc, char * argv[]){ CClass obj; obj.startup( ); return 0; }

编译的时候遇到 C4121 警告:

运行之后遇到 Run-Time Check Failure #0 错误:

传递类成员函数指针导致 Run-Time Check Failure #0 错误与 C4121 结构体对齐警告_第1张图片

最后在 csm.h 文件的 class CCFT 句子前面加上 #include "cft.h" 就可以把所有问题解决;

 

你可能感兴趣的:(传递类成员函数指针导致 Run-Time Check Failure #0 错误与 C4121 结构体对齐警告)