【MFC】CCriticalSection类在Release编译下调用Lock函数会报0xC0000008错误

【MFC】CCriticalSection类在Release编译下调用Lock函数会报错0xC0000008

问题描述

通过以下伪代码方式描述问题:
主对话框类内创建成员变量及结构体变量:

typedef struct MSG_INFO
{
	int a;
	int b;
	char c[10];
}MSGINFO;
MSG_INFO	m_mi;
CCriticalSection m_cs;
CMyDll		m_dll;

在DLL内有一成员变量 :

class MYDLL CMyDll
{
	CCriticalSection *m_pcs;
	MSG_INFO		*m_pmi;
}

现需要实现在DLL工程内能够对主线程内的m_mi进行赋值操作,同时为避免两边现成同时对m_mi进行操作,所以通过以下方式实现关联:

m_dll.m_pcs = &m_cs;
m_dll.m_pmi= &m_mi;

此方法在Debug下调试是可行的,但是在Release下一旦DLL内程序执行到如下代码语句时就会报错:

//DLL内处理代码
m_pcs->Lock();
//功能执行
。。。
m_pcs.Unlock();

后定位到错位位置为Lock()函数内调用API函数::EnterCriticalSection(&m_sect)时便会报错:
在这里插入图片描述
通过分析,个人认为导致此错误的直接原因是m_sect的值是异常导致的(未必正确)
在这里插入图片描述
在这里插入图片描述
但是后面场后过指针,或者对m_sect进行初始化,都无法解决该问题。

在无法发现根本原因,所以只能再次提供两个方法来处理此问题:

方法一 CRITICAL_SECTION代替CCriticalSection

直接声明CRITICAL_SECTION结构体来代替CCriticalSection。

CRITICAL_SECTION   m_cs;
InitializeCriticalSection(&m_cs);

然后还是通过问题描述的方式传递给DLL内成员变量,处理函数修改为:

EnterCriticalSection(m_pcs);
//功能执行
。。。
LeaveCriticalSection(m_pcs);

方法二 使用WaitForSingleObject和ReleaseMutex()

主对话框内定义成员变量并对其进行初始化:

HANDLE m_hMutex;
m_hMutex = CreateMutex(NULL,FALSE,NULL); //第二个参数为FALSEE,互斥对象的所有权为空,处于空闲状态
										//第二个参数为TRUE,互斥对象的所有权为主线程所有,非空闲状态
//DLL传递参数
m_dll.m_hMutex = m_hMutex;

DLL内处理函数修改为:

WaitForSingleObject(m_hMutex , INFINITE);//第二个参数为INFINITE表示一直等待,直到拥有互斥对象
//功能执行
。。。
::ReleaseMutex(m_hMutex);//使用完毕,将互斥对象还给操作系统

说明:
在调用CreateMutex()创建互斥对象时:
若对象所有权为空,则主线程和子线程中分别等待互斥量,即主线程和子线程交替输出;
若标志位TRUE,则互斥对象所有权对创建的线程调用,其余线程无法调用此互斥对象。

此处引用网上的说法:
如创建进程希望立即拥有互斥体,则设为TRUE。一个互斥体同时只能由一个线程拥有。是FALSE,表示刚刚创建的这个Mutex不属于任何线程 也就是没有任何线程拥有他,一个Mutex在没有任何线程拥有他的时候,他是处于激发态的, 所以处于有信号状态。

结语

导致问题出现的根本原因尚未找到,只是在此处提出两个方案来解决此问题,若各位有其他的建议和看法,欢迎来评论区讨论。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值