递归火山软件开发平台

标题: 看到水淼出了进程通讯,我就在想。 [打印本页]

作者: urenai    时间: 2024-3-12 18:25
标题: 看到水淼出了进程通讯,我就在想。
想啥呢?能否轻量化,例如纯纯的使用线程消息来完成通讯呢?
我查了资料,线程是不可以跨进程通讯的。
看情况只能使用窗口消息循坏了。
正好跨窗口postmessage 有个消息号 WM_COPYDATA
  1. COPYDATASTRUCT cds;
  2. cds.dwData = 0; // 自定义数据标识符
  3. cds.cbData = size_of_data; // 数据大小
  4. cds.lpData = data_ptr; // 数据指针
  5. HWND hwndReceiver =    0    ; // 获取目标进程窗口句柄
  6. BOOL result = PostMessage(hwndReceiver, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
复制代码
由此,完全可以做一个类似UDP的简化数据通讯系统,
例如  启动时 使用API ::SetProp(); 标记该主窗口已启动通讯系统,自己身份信息等等。。
这样也可以达到广播效果:调用API::enumwindows(); cha询所有主窗口。凡是存在标志位的皆post之。消息收发效率应该不会太低吧。

有没有火友给封了,最近身体不大好在休息中。



作者: wangvoldp    时间: 2024-3-12 23:14
PostMessage 不能发送 WM_COPYDATA
WM_COPYDATA 自身是申请了一个共享内存将数据写入, 调用sendmessage, 一旦返回代表对方处理完毕,此时可以销毁共享内存, 本轮结束
PostMessage 不管对方是否处理就返回, 难道这时就销毁共享内存么, 那销毁了对方处理消息时就读取不出来了, 不销毁吧又会泄露
作者: wangvoldp    时间: 2024-3-12 23:30
本帖最后由 wangvoldp 于 2024-3-13 02:53 编辑

sendmessage需要等待返回结果,效率太低,
通讯数少的话可以用, 通讯方一多这个等那个,那个等这个, 窗口就卡

异步通讯我想的方法是试用 PostMessage + 共享内存
因为处理的消息队列, 都是主线程操作的不用考虑线程安全,
PostMessage 发送不等待可以保证效率

AB双方协商谁销毁共享内存,
A发送失败就A销毁共享内存,
B收到读取后就B销毁共享内存,


上面方法不行, 创建共享内存后无法在别的进程关闭,只能再想办法了

作者: urenai    时间: 2024-3-13 01:21
wangvoldp 发表于 2024-3-12 23:30
sendmessage需要等待返回结果,效率太低,
通讯数少的话可以用, 通讯方一多这个等那个,那个等这个, 窗口就卡 ...

哦,对!
忘记返回后数据释放问题了。的确只能sendmessage
不过   不用考虑主窗口卡顿阻塞问题,
可以以线程方式新建一个隐藏窗口,
并传入this 直接回调  回调事件。

我是这样想的,不使用 WM_COPYDATA  了。
而是使用 WM_USER  

post内容就简单了,直接是分配内存,把指针 post 给 外部对象窗口。
postmessageW(外部对象窗口句柄, user+1,msg_class,msg_ptr)
指针 包含数据全长+4字节,开头用于记录指针长度。

外部对象窗口得到消息后 调用全局读写进程 readprocessmemory(); 读取指针数据,当然,不是每次都要打开进程。
我们可以给他配一个哈希键值表, 窗口句柄-进程句柄;

取完数据,直接 再调用 postmessage( 告诉 出处对象, user+2,msg_ptr,0) 内部释放指针。

在这里,定义:
user+1 = 接收消息
user+2 = 释放指针
之后有补充的可以再加么,对吧。




作者: urenai    时间: 2024-3-13 01:28
这样 也可以做 类似 UDP 广播。
例如: 枚举主窗口,得到外部  准确对象数量。

再搞一个哈希表,记录 指针 = 外部对象数量,

接到 释放消息时。 外部对象数量-1   归零 则释放,
如果遇到外部对象迟迟不释放咋办,
别急,我们可以再搞个 表继续 指针存活时间,即:指针=取启动时间()
在  线程 窗口 内创建个始终,循环检测维护这张表,例如 1分钟内未释放的指针,强制释放。

再者,顶多 外部对象  丢失消息,绝对不会报错。 因为 readprocessmemory允许读写野指针,只会失败而已。
作者: wangvoldp    时间: 2024-3-13 02:36
urenai 发表于 2024-3-13 01:21
哦,对!
忘记返回后数据释放问题了。的确只能sendmessage
不过   不用考虑主窗口卡顿阻塞问题,

读写内存需要高权限, 不在意权限的话也是可行的, sendmessage即便是隐藏窗口也没法避免发送方的卡顿, 发送后需要切换线程后,那窗口才会处理,处理完,还需要切换线程返回, 1-2个进程或通讯少还行, 一多还是卡, 系统处理那么多窗口一来回也需要时间
作者: lsfeeling    时间: 2024-3-13 11:00
直接udp广播
作者: urenai    时间: 2024-3-13 14:13
哎,歪门邪道,老老实实的封个 命名管道 才是正事。
作者: z3201    时间: 2024-3-13 16:04
本帖最后由 z3201 于 2024-3-13 16:11 编辑

正好有个项目里面用了这个...发送消息用 SendMessageA_跨进程 (hwnd, 74, 0, Msg)  ' #WM_COPYDATA  msg是一个消息类型,可以自己定义,接收的时候是指针,自己解析就是
(, 下载次数: 73)










欢迎光临 递归火山软件开发平台 (https://bbs.voldp.com/) Powered by Discuz! X3.4