urenai 发表于 2024-3-12 18:25:39

看到水淼出了进程通讯,我就在想。

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

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


wangvoldp 发表于 2024-3-12 23:14:53

PostMessage 不能发送 WM_COPYDATA
WM_COPYDATA 自身是申请了一个共享内存将数据写入, 调用sendmessage, 一旦返回代表对方处理完毕,此时可以销毁共享内存, 本轮结束
PostMessage 不管对方是否处理就返回, 难道这时就销毁共享内存么, 那销毁了对方处理消息时就读取不出来了, 不销毁吧又会泄露

wangvoldp 发表于 2024-3-12 23:30:49

本帖最后由 wangvoldp 于 2024-3-13 02:53 编辑

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

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

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

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

urenai 发表于 2024-3-13 01:21:09

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:32

这样 也可以做 类似 UDP 广播。
例如: 枚举主窗口,得到外部准确对象数量。

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

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

再者,顶多 外部对象丢失消息,绝对不会报错。 因为 readprocessmemory允许读写野指针,只会失败而已。

wangvoldp 发表于 2024-3-13 02:36:32

urenai 发表于 2024-3-13 01:21
哦,对!
忘记返回后数据释放问题了。的确只能sendmessage
不过   不用考虑主窗口卡顿阻塞问题,


读写内存需要高权限, 不在意权限的话也是可行的, sendmessage即便是隐藏窗口也没法避免发送方的卡顿, 发送后需要切换线程后,那窗口才会处理,处理完,还需要切换线程返回, 1-2个进程或通讯少还行, 一多还是卡, 系统处理那么多窗口一来回也需要时间

lsfeeling 发表于 2024-3-13 11:00:07

直接udp广播

urenai 发表于 2024-3-13 14:13:05

哎,歪门邪道,老老实实的封个 命名管道 才是正事。

z3201 发表于 2024-3-13 16:04:17

本帖最后由 z3201 于 2024-3-13 16:11 编辑

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






页: [1]
查看完整版本: 看到水淼出了进程通讯,我就在想。