WINCE下进程间通信(二)
WINCE下进程间通信(二)
接着前面的文章《WINCE下进程间通信(一)》,现在介绍进程间通信的另一种方法。
三、管道(消息队列)
WINCE并不支持类似于PC机上匿名管道、命名管道的通信方式,但CE下提供了一种点对点消息队列的方法,其工作原理与管道非常类似:在通信的两端分别建立一个读队列和写队列,写进程往消息队列一端写入数据,读进程从消息队列另一端读取数据。
消息队列相关的系统API主要有:CreateMsgQueue()、ReadMsgQueue()、WriteMsgQuue()和CloseMsgQueue()。为了方便消息队列的操作,封装了一个消息队列操作类,参考代码如下:
头文件(CMsgQueue.h)
- /*******************************************************************
- filename: CMsgQueue.h
- purpose: 封装了WINCE下消息队列操作类
- author: firehood
- created: 2011.03.23
- ********************************************************************/
- #ifndef _MSG_QUEUE_H
- #define _MSG_QUEUE_H
- // 消息队列访问模式
- enum ACCESSMODE
- {
- ReadMode = 0,
- WriteMode
- };
- // 定义消息回调函数
- typedef BOOL (CALLBACK *MsgQueueCallBack)(PVOID pData, DWORD dwSize);
- class CMsgQueue
- {
- public:
- CMsgQueue();
- CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
- ~CMsgQueue();
- public:
- /**********************************************************************
- 函数名:Create
- 功能: 创建或打开消息队列
- 参数:
- [in]lpQueueName: 消息队列名称
- [in]dwSize: 每条消息的最大长度
- [in]accessMode 消息队列访问模式 ReadMode:只读 WriteMode:只写
- 返回值:
- 成功:TRUE 失败:FALSE
- **********************************************************************/
- BOOL Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
- /**********************************************************************
- 函数名:Read
- 功能: 从消息队列中读取一条消息
- 参数:
- [out]lpBuffer: 存放读取的数据
- [in] dwSize: 读取数据的大小
- [out]lpNumberOfBytesRead 实际读取数据的大小
- [in] dwTimeout 读取超时时间(ms) 0 立即返回 INFINITE 永远等待直至消息队列中有数据
- 返回值:
- 成功:TRUE 失败:FALSE
- ***********************************************************************/
- BOOL Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout = 0);
- /**********************************************************************
- 函数名:Write
- 功能: 向消息队列中写入一条消息
- 参数:
- [in]lpBuffer: 待写入的数据
- [in]dwSize: 写入数据的大小
- 返回值:
- 成功:TRUE 失败:FALSE
- **********************************************************************/
- BOOL Write(LPVOID lpBuffer,DWORD dwSize);
- // 设置消息回调函数
- BOOL SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam);
- // 关闭消息队列
- void Close(void);
- private:
- // 开启读取消息线程
- BOOL StartRevMsgThread(void);
- // 停止读取消息线程
- BOOL StopRevMsgThread(void);
- // 读取消息线程
- static void WINAPI RevMsgThread(LPVOID pParam);
- private:
- HANDLE m_hMsgQueue;
- DWORD m_dwQueueSize;
- MsgQueueCallBack m_MsgCallBack;
- HANDLE m_hRevMsgThread;
- BOOL m_bThreadExit;
- };
- #endif
/*******************************************************************
filename: CMsgQueue.h
purpose: 封装了WINCE下消息队列操作类
author: firehood
created: 2011.03.23
********************************************************************/
#ifndef _MSG_QUEUE_H
#define _MSG_QUEUE_H
// 消息队列访问模式
enum ACCESSMODE
{
ReadMode = 0,
WriteMode
};
// 定义消息回调函数
typedef BOOL (CALLBACK *MsgQueueCallBack)(PVOID pData, DWORD dwSize);
class CMsgQueue
{
public:
CMsgQueue();
CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
~CMsgQueue();
public:
/**********************************************************************
函数名:Create
功能: 创建或打开消息队列
参数:
[in]lpQueueName: 消息队列名称
[in]dwSize: 每条消息的最大长度
[in]accessMode 消息队列访问模式 ReadMode:只读 WriteMode:只写
返回值:
成功:TRUE 失败:FALSE
**********************************************************************/
BOOL Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode);
/**********************************************************************
函数名:Read
功能: 从消息队列中读取一条消息
参数:
[out]lpBuffer: 存放读取的数据
[in] dwSize: 读取数据的大小
[out]lpNumberOfBytesRead 实际读取数据的大小
[in] dwTimeout 读取超时时间(ms) 0 立即返回 INFINITE 永远等待直至消息队列中有数据
返回值:
成功:TRUE 失败:FALSE
***********************************************************************/
BOOL Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout = 0);
/**********************************************************************
函数名:Write
功能: 向消息队列中写入一条消息
参数:
[in]lpBuffer: 待写入的数据
[in]dwSize: 写入数据的大小
返回值:
成功:TRUE 失败:FALSE
**********************************************************************/
BOOL Write(LPVOID lpBuffer,DWORD dwSize);
// 设置消息回调函数
BOOL SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam);
// 关闭消息队列
void Close(void);
private:
// 开启读取消息线程
BOOL StartRevMsgThread(void);
// 停止读取消息线程
BOOL StopRevMsgThread(void);
// 读取消息线程
static void WINAPI RevMsgThread(LPVOID pParam);
private:
HANDLE m_hMsgQueue;
DWORD m_dwQueueSize;
MsgQueueCallBack m_MsgCallBack;
HANDLE m_hRevMsgThread;
BOOL m_bThreadExit;
};
#endif
源文件(CMsgQueue.cpp)
- #include "stdafx.h"
- #include "CMsgQueue.h"
- CMsgQueue::CMsgQueue()
- {
- m_hMsgQueue = NULL;
- m_dwQueueSize = 0;
- m_hRevMsgThread = NULL;
- m_bThreadExit = FALSE;
- m_MsgCallBack = NULL;
- }
- CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
- {
- Create(lpQueueName,dwSize,accessMode);
- }
- CMsgQueue::~CMsgQueue()
- {
- Close();
- }
- BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
- {
- if(!m_hMsgQueue)
- {
- m_hRevMsgThread = NULL;
- m_bThreadExit = FALSE;
- m_MsgCallBack = NULL;
- m_dwQueueSize = dwSize;
- // 创建消息队列
- MSGQUEUEOPTIONS options;
- options.dwSize = sizeof(options);
- options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;
- options.dwMaxMessages = 0;
- options.cbMaxMessage = dwSize;
- options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;
- m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);
- }
- return TRUE;
- }
- void CMsgQueue::Close(void)
- {
- if(m_hMsgQueue)
- {
- ::CloseMsgQueue(m_hMsgQueue);
- m_hMsgQueue = NULL;
- }
- // 注销回调函数
- SetMsgCallBack(NULL,NULL);
- }
- BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)
- {
- if(m_hMsgQueue == NULL || lpBuffer == NULL)
- {
- return FALSE;
- }
- DWORD dwFlag = 0;
- // 从消息队列头部读出数据
- if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)
- {
- if(m_hMsgQueue == NULL || lpBuffer == NULL)
- {
- return FALSE;
- }
- // 向消息队列尾部写入数据
- if(!::WriteMsgQueue(m_hMsgQueue,lpBuffer,dwSize,0,0))
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)
- {
- m_MsgCallBack = pCallBackFun;
- if (m_MsgCallBack)
- {
- if (m_hRevMsgThread == NULL)
- {
- // 开启读取线程
- return StartRevMsgThread();
- }
- }
- else
- {
- if (m_hRevMsgThread)
- {
- // 关闭读取线程
- return StopRevMsgThread();
- }
- }
- return TRUE;
- }
- BOOL CMsgQueue::StartRevMsgThread(void)
- {
- if(m_hRevMsgThread == NULL)
- {
- // 创建读取消息线程
- m_hRevMsgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CMsgQueue::RevMsgThread, this, 0, NULL);
- }
- return (m_hRevMsgThread ? TRUE : FALSE);
- }
- BOOL CMsgQueue::StopRevMsgThread(void)
- {
- if(m_hRevMsgThread)
- {
- m_bThreadExit = TRUE;
- // 等待线程成功退出
- WaitForSingleObject(m_hRevMsgThread,INFINITE);
- CloseHandle(m_hRevMsgThread);
- m_hRevMsgThread = NULL;
- m_hRevMsgThread = FALSE;
- }
- return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
- }
- void WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
- {
- CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
- LPVOID lpBuffer;
- DWORD dwReadNums=0;
- lpBuffer=(LPVOID)malloc(pMsgQueue->m_dwQueueSize);
- while(!pMsgQueue->m_bThreadExit)
- {
- if(!pMsgQueue->m_hMsgQueue )
- break;
- // 从消息队列中读取一条消息(阻塞模式)
- BOOL ret=pMsgQueue->Read(lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
- printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
- if(dwReadNums>0)
- {
- // 调用回调函数
- if(pMsgQueue->m_MsgCallBack)
- pMsgQueue->m_MsgCallBack(lpBuffer,dwReadNums);
- }
- }
- printf("RevMsgThread exit.../n");
- free(lpBuffer);
- }
#include "stdafx.h"
#include "CMsgQueue.h"
CMsgQueue::CMsgQueue()
{
m_hMsgQueue = NULL;
m_dwQueueSize = 0;
m_hRevMsgThread = NULL;
m_bThreadExit = FALSE;
m_MsgCallBack = NULL;
}
CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
Create(lpQueueName,dwSize,accessMode);
}
CMsgQueue::~CMsgQueue()
{
Close();
}
BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
if(!m_hMsgQueue)
{
m_hRevMsgThread = NULL;
m_bThreadExit = FALSE;
m_MsgCallBack = NULL;
m_dwQueueSize = dwSize;
// 创建消息队列
MSGQUEUEOPTIONS options;
options.dwSize = sizeof(options);
options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;
options.dwMaxMessages = 0;
options.cbMaxMessage = dwSize;
options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;
m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);
}
return TRUE;
}
void CMsgQueue::Close(void)
{
if(m_hMsgQueue)
{
::CloseMsgQueue(m_hMsgQueue);
m_hMsgQueue = NULL;
}
// 注销回调函数
SetMsgCallBack(NULL,NULL);
}
BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)
{
if(m_hMsgQueue == NULL || lpBuffer == NULL)
{
return FALSE;
}
DWORD dwFlag = 0;
// 从消息队列头部读出数据
if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))
{
return FALSE;
}
return TRUE;
}
BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)
{
if(m_hMsgQueue == NULL || lpBuffer == NULL)
{
return FALSE;
}
// 向消息队列尾部写入数据
if(!::WriteMsgQueue(m_hMsgQueue,lpBuffer,dwSize,0,0))
{
return FALSE;
}
return TRUE;
}
BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)
{
m_MsgCallBack = pCallBackFun;
if (m_MsgCallBack)
{
if (m_hRevMsgThread == NULL)
{
// 开启读取线程
return StartRevMsgThread();
}
}
else
{
if (m_hRevMsgThread)
{
// 关闭读取线程
return StopRevMsgThread();
}
}
return TRUE;
}
BOOL CMsgQueue::StartRevMsgThread(void)
{
if(m_hRevMsgThread == NULL)
{
// 创建读取消息线程
m_hRevMsgThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CMsgQueue::RevMsgThread, this, 0, NULL);
}
return (m_hRevMsgThread ? TRUE : FALSE);
}
BOOL CMsgQueue::StopRevMsgThread(void)
{
if(m_hRevMsgThread)
{
m_bThreadExit = TRUE;
// 等待线程成功退出
WaitForSingleObject(m_hRevMsgThread,INFINITE);
CloseHandle(m_hRevMsgThread);
m_hRevMsgThread = NULL;
m_hRevMsgThread = FALSE;
}
return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
}
void WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
{
CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
LPVOID lpBuffer;
DWORD dwReadNums=0;
lpBuffer=(LPVOID)malloc(pMsgQueue->m_dwQueueSize);
while(!pMsgQueue->m_bThreadExit)
{
if(!pMsgQueue->m_hMsgQueue )
break;
// 从消息队列中读取一条消息(阻塞模式)
BOOL ret=pMsgQueue->Read(lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
if(dwReadNums>0)
{
// 调用回调函数
if(pMsgQueue->m_MsgCallBack)
pMsgQueue->m_MsgCallBack(lpBuffer,dwReadNums);
}
}
printf("RevMsgThread exit.../n");
free(lpBuffer);
}
使用CMsgQueue类实现进程间通信:
- // 发送进程
- //////////////////////////////////////////////////////////////////////////////////
- // 创建只写消息队列
- CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
- // 往消息队列写数据
- cMsgQueue.Write(L"Hello Word!",22);
- cMsgQueue.Close();
- //////////////////////////////////////////////////////////////////////////////////
- // 接收进程
- //////////////////////////////////////////////////////////////////////////////////
- // 声明消息回调函数
- BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize);
- // 创建只读消息队列
- CMsgQueue cMsgQueue(L"MsgQueueTest",1024,ReadMode);
- // 设置消息回调函数
- cMsgQueue.SetMsgCallBack(RecvMsgProc,NULL);
- // 处理消息
- BOOL CALLBACK RecvMsgProc(PVOID pData, DWORD dwSize)
- {
- printf("RecvMsgProc:Rev data Size=%d/n",dwSize);
- wchar_t data[256];
- memcpy(data, pData,dwSize);
- return TRUE;
- }
- //////////////////////////////////////////////////////////////////////////////////
WINCE下进程间通信(二)的更多相关文章
- WINCE下进程间通信(一)
WINCE下进程间通信(一) 在WINCE开发中经常需要在不同的进程之间传递.共享数据,总结了一下,WINCE下进程间通信常用的方式有:Windows消息,共享内存,socket通信,管道,全局原子, ...
- Linux环境进程间通信(二):信号(下)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- Wince下sqlce数据库开发(二)
上次写到使用数据绑定的方法测试本地sqlce数据库,这次使用访问SQL Server的方法访问sqlce,你会发现他们是如此的相似... 参考资料:http://www.cnblogs.com/rai ...
- 在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发
点击打开链接 背景 在开发3G项目的是时候,发现尽管3G网络连接已经建立成功了,但是数据不能发送成功,查明原因,由于路由表的问题,导致数据往ActiveSync连接的对端,也就是PC发送,而不是发送到 ...
- Linux环境进程间通信(二): 信号(上)
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- WinCE下SQLCE数据库开发(VS,VB.net,VC++)
WinCE下SQLCE数据库开发(VS,VB.net,VC++) WinCE下SQLCE数据库开发 微软的SQL Server数据库由于其功能强大.方便使用,因此在很多行业都被广泛应用.基于智能设 ...
- WinCE下的串口通信开发(VS2005,VB.Net,VC++)
WinCE下的串口通信开发(VS2005,VB.Net,VC++) WinCE下的串口通信开发 一.利用Visual Basic 开发很简单,因为有现成的控件可以直接调用 以VS2005为例,首先 ...
- WinCE下读取注册表获得SD路径
WinCE下读取注册表获得SD路径 [要点]WinCE注册表中[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMemory\] 下键Folde ...
- WinCE下GPRS自动拨号软件(GPRS AutoDial)
之前在WinCE下调试USB的3G Modem时,写过一个拨号助手RASManager,基本能用.后来车机卖到俄罗斯去,客户老M提供了一个更好的GPRS自动拨号软件GPRS AutoDial,功能完善 ...
随机推荐
- JavaScript高级程序设计:第八章
1.window对象——BOM的核心 BOM的核心对象时window,它表示浏览器的一个实例.在浏览器中,window对象有双重角色,它既是通过javascript访问浏览器窗口的一个接口,又是ECM ...
- Memcached缓存
Memcached是"分布式"的内存对象缓存系统,那么不需要"分布"的.不需要共享的或者干脆规模小到只有一台服务器的应用,Memcached不会带来任何好处,相 ...
- Sharepoint 弹出消息提示框 .
在event receiver中如何弹出一个类似winform中messagebox.show 的框? 那我要对用户显示一些错误信息或者提示信息怎么搞? 1. 如果是在ItemAdding或者其他进行 ...
- flash 右键菜单隐藏与修改
来源:http://blog.sina.com.cn/s/blog_7264c84401014fmd.html import flash.ui.ContextMenu;import flash.ui. ...
- 初识Iaas,paas
Iaas(Infrastructure-as-a-service),直译为基础设备作为一种服务. Paas(Platform as a service),直译为平台作为一种服务. 暂且忘掉这两个单词, ...
- PHP: 异常exception
异常最常见于SDK调用中,函数执行失败时抛出异常,顺带错误码和错误信息. 先来看下PHP的异常处理相关函数: public Exception::__construct() ([ string $me ...
- js中冒泡事件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MySQL慢日志查询全解析:从参数、配置到分析工具【转】
转自: MySQL慢日志查询全解析:从参数.配置到分析工具 - MySQL - DBAplus社群——围绕数据库.大数据.PaaS云,运维圈最专注围绕“数据”的学习交流和专业社群http://dbap ...
- WPF之TabControl控件用法
先创建实体基类:NotificationObject(用来被实体类继承) 实现属性更改通知接口: using System; using System.Collections.Generic; usi ...
- 虚拟机centos分区
在计算机上安装 Linux 系统,对硬盘进行分区是一个非常重要的步骤,下面介绍几个分区方案. 方案 1 / :建议大小在 5GB 以上. swap :即交换分区,建议大小是物理内存的 1~2 倍. 方 ...