被人遗忘的进程通讯解决方案

我们总是会选择不同的方案来实现IPC,本地SOCK通讯决然是最好的选择,但往往
敏捷实现一套安全的IPC通讯设计又是那么的吃力。而此时我们在确定系统平台的
同时,能够吸纳现存的东西使自身的困难的变的简单,使有限的时间变的有意义。


-----------------------通过windows消息发送数据-------------------------

检索黏贴,来自windows核心编程:

对于系统已经知道的消息,发送消息时都可以按相应的方式来处理。如果你要建立
自己的(WM_USER+x)消息,并从一个进程向另一个进程的窗口发送,那又
会怎么样?系统不知道你要用内存映像文件并在发送消息时改变指针。为此,微软
建立了一个特殊的窗口消息,WM_COPYDATA以解决这个问题:

COPYDATASTRUCTcds;
SendMessage(hwndReceiver,WM_COPYDATA,
(WPARAM)hwndSender,(LPARAM)&cds);

COPYDATASTRUCT是一个结构,定义在WinUser.h文件中,形式如
下面的样子:

typedefstructtagCOPYDATASTRUCT
{
ULONG_PTRdwData;
DWORDcbData;
PVOIDlpData;
}COPYDATASTRUCT;

当一个进程要向另一个进程的窗口发送一些数据时,必须先初始化COPYDATASTRUCT结构
数据成员dwData是一个备用的数据项,可以存放任何值。例如,你有可能向另外的进程
发送不同类型或不同类别的数据。可以用这个数据来指出要发送数据的内容。
cbData数据成员规定了向另外的进程发送的字节数,lpData数据成员指向要
发送的第一个字节。lpData所指向的地址,当然在发送进程的地址空间中。

当SendMessage看到要发送一个WM_COPYDATA消息时,它建立一个内存
映像文件,大小是cbData字节,并从发送进程的地址空间中向这个内存映像文件中复
制数据。然后再向目的窗口发送消息。在接收消息的窗口过程处理这个消息时,lParam
参数指向已在接收进程地址空间的一个COPYDATASTRUCT结构。这个结构的lpData
成员指向接收进程地址空间中的共享内存映像文件的视图。

关于WM_COPYDATA消息,应该注意三个重要问题:

*只能发送这个消息,不能登记这个消息。不能登记一个WM_COPYDATA消息,因为在接
收消息的窗口过程处理完消息之后,系统必须释放内存映像文件。如果登记这个消息,
系统不知道这个消息何时被处理,所以也不能释放复制的内存块。

*系统从另外的进程的地址空间中复制数据要花费一些时间。所以不应该让发送程序中
运行的其他线程修改这个内存块,直到SendMessage调用返回。


利用WM_COPYDATA消息,可以实现16位和32位之间的通信。它也能实现32位与64位之间的
通信。这是使新程序同旧程序交流的便捷方法。注意在Windows2000和Windows98上完全
支持WM_COPYDATA。但如果你依然在编写16位Windows程序,MicrosofeVisualC++1.52没
有WM_COPYDATA消息的定义,也没有COPYDATASTRUCT结构的定义。需要手工添加这些代码:

//Manually include this in your 16-bit Windows sourcecode.
#defineWM_COPYDATA0x004A

typedefVOIDFAR*PVOID;
typedefstructtagCOPYDATASTRUCT
{
DWORDdwData;
DWORDcbData;
PVOIDlpData;
}COPYDATASTRUCT,FAR*PCOPYDATASTRUCT;

比如,一段用windows窗口发消息到skype的应用代码:

BOOL CHwSkype::SendMsg ( LPCTSTR lpszMsg, ... )
{
if ( !lpszMsg || strlen(lpszMsg) < 1 ) return FALSE;
if ( !InitIsOK() ) return FALSE;

COPYDATASTRUCT CopyData = {0};
char buf[1024] = {0};
va_list va;
va_start ( va, lpszMsg );
_vsnprintf ( buf, sizeof(buf) - 1, (char*)lpszMsg, va);
va_end(va);

CopyData.dwData = 0;
CopyData.lpData = (PVOID)buf;
CopyData.cbData = strlen(buf)+1;
if ( SendMessage ( m_hWnd_Skype, WM_COPYDATA, WPARAM(m_hWnd_MainWindow),
LPARAM(&CopyData)) == 0 )
{
Log ( "Send message [%s] failed", lpszMsg );
return FALSE;
}
return TRUE;
}

windows编程虽古老而耐用,东西学不完,只取其一斑!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值