在下有一个程序,需要HOOK到目标进程中然后传递数据进行通信。
以前因为传递频率不是很高,简单的使用了内存映射来解决问题,一方创建内存映射并使用定时器随时准备读取数据,另一头读取映射并写入数据。
原本这样的做法没有什么大问题的,可是因为需求的改变,传递数据的频率变得有点高了(其实也就是一秒几次的样子),使得这种传递方式变得好像不是很保险,于是在部分电脑上出现了传递不及时导致程序错误的现象。
为了解决这个问题,我就使用了SENDMESSAGE和COPYDATA的方式来传递数据,又因为传递过来的数据需要在使用时才调用,所以当数据到达时,我使用了一个STL Queue的队列来进行存放。结果,奇葩的问题出现了:在小部分电脑上出现了从队列中取出的数据完全不正确的现象!
刚开始我以为是进程间通信产生的问题,于是在COPYDATA中获取到传递数据时写了调试信息进行记录,结果发现从收到数据一直到PUSH入QUEUE队列的时候都是完全正确的,就是当再次从队列中取出的时候,数据才完全变了样(比如存进去的是2,取出来的变成15之类……)。
收到数据时,我不放心,是先做了记录再PUSH的:
out_data *data = (out_data*)pCopyDataStruct->lpData;
out_data tmp = {0};
memcpy(&tmp, data, sizeof(tmp));
sprintf(m_log, "收到从HOOK传递过来的数据%d", tmp.num);
Log(m_log);
m_outque.push(tmp);
sprintf(m_log, "将收到的数据PUSH入队列");
Log(m_log);
队列的数据结构也极简单,就是这个样子:
struct out_data
{
int num;
char data[20 * 2];
};
typedef std::queue<out_data> outque;
使用队列的代码都处于同一个线程、同一个类里面,不存在异步问题;而且经过对代码的反复检查,也能肯定除了压入和取出这两处外,没有别的地方对队列进行过任何操作和干涉。这段代码的程序在超过两百台电脑上测试过,绝大部分都运行正常,实际反馈出现这个问题的主要是几台装了WIN7系统,而硬件配置又比较老的电脑。也试过把QUEUE改成Vector,在没出问题的电脑上依旧正常,但出问题的电脑上还是照样出错。
程序的编译环境:VS 2005 MFC DLL程序
不知道有没有人遇到过类似的错误,或者知道问题的根源能够指点一下的?
至为感谢