WINCE下进程间通信(一)
WINCE下进程间通信(一)
在WINCE开发中经常需要在不同的进程之间传递、共享数据,总结了一下,WINCE下进程间通信常用的方式有:Windows消息,共享内存,socket通信,管道,全局原子,邮槽等,下面就分别对这几种方法做个小结。(当然还可以采用注册表,磁盘文件以及数据库方式,只是这几种方式的通信效率和实时性比较低,所以一般不考虑。)
一、Windows消息
通过Windows消息,可以很方便的在进程与进程之间传递数据。对于传递像字符串这种小的数据,可以直接将字符串以消息参数wParam、lParam的方式传递给其他进程,对于大一点的数据,可以采用发送WM_COPYDATA消息,参考代码如下:
- void SendMsg(HWND hwnd,LPVOID lpData,DWORD dwSize)
- {
- // 填充COPYDATASTRUCT结构
- COPYDATASTRUCT cpd;
- cpd.cbData = dwSize;
- cpd.lpData = lpData;
- // 向指定窗口发送WM_COPYDATA消息,不能用PostMessage方式发送
- ::SendMessage(hwnd, WM_COPYDATA, NULL,(LPARAM)&cpd);
- }
- // 发送端
- TCHAR *data=_T("要发送的内容");
- SendMsg(::FindWindow(NULL,_T("processB")),(void*)data,_tcslen(data)*2);
void SendMsg(HWND hwnd,LPVOID lpData,DWORD dwSize)
{
// 填充COPYDATASTRUCT结构
COPYDATASTRUCT cpd;
cpd.cbData = dwSize;
cpd.lpData = lpData;
// 向指定窗口发送WM_COPYDATA消息,不能用PostMessage方式发送
::SendMessage(hwnd, WM_COPYDATA, NULL,(LPARAM)&cpd);
}
// 发送端
TCHAR *data=_T("要发送的内容");
SendMsg(::FindWindow(NULL,_T("processB")),(void*)data,_tcslen(data)*2);
在接收端的窗口过程处理函数中添加对WM_COPYDATA消息的处理
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- PAINTSTRUCT ps;
- HDC hdc;
- TCHAR data[256]={0};
- switch (message)
- {
- case WM_COPYDATA:
- {
- COPYDATASTRUCT *pCopyDataStruct=(COPYDATASTRUCT *)lParam;
- memcpy(data,pCopyDataStruct->lpData,pCopyDataStruct->cbData);
- }
- break;
- // ...
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR data[256]={0};
switch (message)
{
case WM_COPYDATA:
{
COPYDATASTRUCT *pCopyDataStruct=(COPYDATASTRUCT *)lParam;
memcpy(data,pCopyDataStruct->lpData,pCopyDataStruct->cbData);
}
break;
// ...
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
需要注意的是在发送数据量较大且数据交换频繁的时候通过发送WM_COPYDATA消息是不可取的,因为当数据传输过于频繁时将有可能导致数据的丢失。
二、共享内存
共享内存顾名思义是在内存中创建一个公共区域,供不同的进程间的数据共享。因为是直接对内存进行读写操作,效率非常高,所以共享内存特别适用于大批量的数据传输且实时性要求比较高的场合。
具体操作步骤如下:
1.进程A调用CreateFileMapping创建一个内存映射文件。
2.进程A调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy往内存中拷贝数据。
3.进程B调用CreateFileMapping打开进程A创建的内存映射文件。
4.进程B调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy从内存中读出数据。
5.通信完后进程A,B分别调用UnmapViewOfFile,CloseHandle取消内存映射和关闭内存映射对象句柄。
为了简化操作,这里封装了一个共享内存操作类,参考代码如下:
头文件CShareMemory.h:
- /*******************************************************************
- filename: CShareMemory.h
- purpose: 封装了共享内存操作类
- author: firehood
- created: 2011.03.16
- ********************************************************************/
- #ifndef _SHARE_MEMORY_H
- #define _SHARE_MEMORY_H
- class CShareMemory
- {
- public:
- CShareMemory();
- ~CShareMemory();
- public:
- /**********************************************************
- 函数名:Open
- 功能: 创建或打开内存映射文件
- 参数:
- [in]szMapName: 要创建的共享内存名称
- [in]dwSize: 创建共享内存的大小
- 返回值:
- 0: 失败
- 1: 创建成功
- 2: 文件已存在
- ***********************************************************/
- DWORD Open(LPCTSTR szMapName,DWORD dwSize);
- /**********************************************************
- 函数名:Read
- 功能: 从共享内存指定位置读取数据
- 参数:
- [out]pBuf: 存放读取的数据
- [in]dwSize: 读取数据的大小
- [in]dwOffset 距共享内存起始位置的偏移量
- 返回值:
- TRUE: 成功 FALSE:失败
- ***********************************************************/
- BOOL Read(void* pBuf,DWORD dwSize,DWORD dwOffset = 0);
- /**********************************************************
- 函数名:Write
- 功能: 从共享内存指定位置写入数据
- 参数:
- [in]pBuf: 待写入的数据指针
- [in]dwSize: 写入数据的大小
- [in]dwOffset 距共享内存起始位置的偏移量
- 返回值:
- TRUE: 失败 FALSE:失败
- ***********************************************************/
- BOOL Write(const void* pBuf,DWORD dwSize,DWORD dwOffset = 0);
- void Close(void);
- private:
- HANDLE m_hShareMemory;
- LPVOID m_pMapBuffer;
- HANDLE m_hAccessMutex;
- };
- #endif
/*******************************************************************
filename: CShareMemory.h
purpose: 封装了共享内存操作类
author: firehood
created: 2011.03.16
********************************************************************/
#ifndef _SHARE_MEMORY_H
#define _SHARE_MEMORY_H
class CShareMemory
{
public:
CShareMemory();
~CShareMemory();
public:
/**********************************************************
函数名:Open
功能: 创建或打开内存映射文件
参数:
[in]szMapName: 要创建的共享内存名称
[in]dwSize: 创建共享内存的大小
返回值:
0: 失败
1: 创建成功
2: 文件已存在
***********************************************************/
DWORD Open(LPCTSTR szMapName,DWORD dwSize);
/**********************************************************
函数名:Read
功能: 从共享内存指定位置读取数据
参数:
[out]pBuf: 存放读取的数据
[in]dwSize: 读取数据的大小
[in]dwOffset 距共享内存起始位置的偏移量
返回值:
TRUE: 成功 FALSE:失败
***********************************************************/
BOOL Read(void* pBuf,DWORD dwSize,DWORD dwOffset = 0);
/**********************************************************
函数名:Write
功能: 从共享内存指定位置写入数据
参数:
[in]pBuf: 待写入的数据指针
[in]dwSize: 写入数据的大小
[in]dwOffset 距共享内存起始位置的偏移量
返回值:
TRUE: 失败 FALSE:失败
***********************************************************/
BOOL Write(const void* pBuf,DWORD dwSize,DWORD dwOffset = 0);
void Close(void);
private:
HANDLE m_hShareMemory;
LPVOID m_pMapBuffer;
HANDLE m_hAccessMutex;
};
#endif
源文件CShareMemory.cpp:
- #include "stdafx.h"
- #include "CShareMemory.h"
- CShareMemory::CShareMemory()
- {
- m_hShareMemory = NULL;
- m_pMapBuffer = NULL;
- m_hAccessMutex =NULL;
- }
- CShareMemory::~CShareMemory()
- {
- Close();
- }
- DWORD CShareMemory::Open(LPCTSTR szMapName,DWORD dwSize)
- {
- DWORD dwRet = 1;
- if(szMapName == NULL)
- return 0;
- if(m_hShareMemory)
- {
- Close();
- }
- // 创建内存映射文件对象
- m_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,dwSize,szMapName);
- if(!m_hShareMemory)
- {
- return 0;
- }
- // 内存映射文件对象已存在
- if(GetLastError() == ERROR_ALREADY_EXISTS)
- {
- dwRet = 2;
- }
- // 获取内存映射文件指针
- m_pMapBuffer = MapViewOfFile(m_hShareMemory,FILE_MAP_ALL_ACCESS,0,0,0);
- if(!m_pMapBuffer)
- {
- CloseHandle(m_hShareMemory);
- return 0;
- }
- // 创建互斥体,用于读写同步
- TCHAR szMutexName[MAX_PATH];
- _tcscpy(szMutexName, szMapName);
- _tcscat(szMutexName, _T("_Mutex"));
- m_hAccessMutex=CreateMutex(NULL, FALSE, szMutexName);
- if(!m_hAccessMutex)
- {
- Close();
- return 0;
- }
- return dwRet;
- }
- BOOL CShareMemory::Read(void* pBuf,DWORD dwSize,DWORD dwOffset)
- {
- BOOL bRet;
- if(!m_pMapBuffer) return FALSE;
- if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
- {
- memcpy(pBuf,(BYTE*)m_pMapBuffer+dwOffset,dwSize);
- bRet = TRUE;
- }
- ReleaseMutex(m_hAccessMutex);
- return bRet;
- }
- BOOL CShareMemory::Write(const void* pBuf,DWORD dwSize,DWORD dwOffset)
- {
- BOOL bRet;
- if(!m_pMapBuffer) return FALSE;
- if(WaitForSingleObject(m_hAccessMutex,INFINITE)==WAIT_OBJECT_0)
- {
- memcpy((BYTE*)m_pMapBuffer+dwOffset,pBuf,dwSize);
- bRet = TRUE;
- }
- ReleaseMutex(m_hAccessMutex);
- return TRUE;
- }
- void CShareMemory::Close(void)
- {
- if(m_hShareMemory)
- {
- UnmapViewOfFile(m_pMapBuffer);
- CloseHandle(m_hShareMemory);
- m_pMapBuffer = NULL;
- m_hShareMemory = NULL;
- }
- if(m_hAccessMutex)
- {
- CloseHandle(m_hAccessMutex);
- m_hAccessMutex = NULL;
- }
- }
WINCE下进程间通信(一)的更多相关文章
- WINCE下进程间通信(二)
WINCE下进程间通信(二) 接着前面的文章<WINCE下进程间通信(一)>,现在介绍进程间通信的另一种方法. 三.管道(消息队列) WINCE并不支持类似于PC机上匿名管道.命名管道的通 ...
- 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,功能完善 ...
- Wince下sqlce数据库开发(二)
上次写到使用数据绑定的方法测试本地sqlce数据库,这次使用访问SQL Server的方法访问sqlce,你会发现他们是如此的相似... 参考资料:http://www.cnblogs.com/rai ...
- Wince下sqlce数据库开发(一)
对于Wince下的sqlce数据库虽然很多人在用,但在我查找资料时,却发现资料是多么的匮乏,在此对自己这几天的了解做个简单介绍,希望对大家能有所帮助! 本文的最后附有所使用到的sqlce在wince下 ...
- 浅析Linux下进程间通信:共享内存
浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...
- 在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发
点击打开链接 背景 在开发3G项目的是时候,发现尽管3G网络连接已经建立成功了,但是数据不能发送成功,查明原因,由于路由表的问题,导致数据往ActiveSync连接的对端,也就是PC发送,而不是发送到 ...
- WinCE下使用C#获得带毫秒的DateTime.Now
在WinCE下,使用DateTime.Now获取的系统时间是不带毫秒的,如果想要它带毫秒,需要耍点手段.话不多说,直接上代码: public static DateTimePrecisely { // ...
- wince下sources\sources.cmn\Makefile.def的相关作用
1:首先是Makefile.def: ---------------------------------------- 在所有驱动的makefile中有!INCLUDE $(_MAKEENVROOT) ...
随机推荐
- POJ 2239 Selecting Courses
二分图的最大匹配.课程和时间可以看做二分图. #include<cstdio> #include<cstring> #include<cmath> #include ...
- js去除字符串中所有html标签及 符号
近日在做项目的时候,经常会在页面上处理一些数据.结果发现自己js掌握的并不是很好.那就在这里记录js的点点滴滴吧. 1. 去除字符串中的 html 标签 function delHtmlTag(str ...
- 让AutoMapper在你的项目里飞一会儿(转)
出处:http://www.cnblogs.com/WeiGe/p/3835523.html 先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说 ...
- JqGrid动态改变列名
setLabel colname, data, class, properties jqGrid对象 给指定列设置一个新的显示名称.colname:列名称,也可以是列的位置索引,从0开始:data:列 ...
- <marquee>,视频和音频的插入,正则表达式
1.marquee 页面的自动滚动效果,不仅可以移动文字,也可以移动图片表格. <marquee></marquee>之间加内容即可. marquee的属性 1.滚动方向dir ...
- IE11中的F12无效的问题
最近做的一个项目中,h5中的video标签IE11在有的机器上兼容,有的机器上不兼容,很是让人头疼.将IE卸载后重装又发现最新的IE11中F12开发者工具失效.面对F12失效的问题,具体解决办法如下: ...
- Ansible10:Playbook的角色与包含【转】
当单个playbook文件越来越大的时候,我们就需要重新来组织Playbooks了.我们可以将一个大的playbook拆成若干个小的playbook文件,然后通过include的方式,在主配置文件中将 ...
- flowers
问题大全 Do you like flowers?(Why?) What flowers do you like?(why?) What is your favorite flower? Are fl ...
- 尚未配置为Web项目.指定的本地IIS URL http://localhsst/..要打开项目,需要配置虚拟目录 。是否立即创建虚拟目录 解决
1.编辑.csproj文件 2.修改 UseIIS节点改为false,再次打开程序即可
- php事件驱动
1. [文件] class.Dispatcher.php ~ 967B 下载(9) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...