Qt 用Windows进程间通信 发送结构体,结构体内容中不能有QString格式吗?

TOBY110 2017-01-09 03:16:29
请看源码:
1.发送方:
void Sender::onSendMessage()
{
HWND hwnd = NULL;
LPWSTR path = (LPWSTR)c_strTitle.utf16(); //path = L"SendMessage"
hwnd = ::FindWindowW(NULL,path);
if(::IsWindow(hwnd))
{
struct test
{
QSting tq;
float tf;
int ti;
}tt;
tt.tf=3.14;
tt.ti=5;
tt.tq="abcd";
COPYDATASTRUCT copydata;
copydata.dwData = CUSTOM_TYPE; //自定义用户号
copydata.lpData = &tt; //指向数据的指针
copydata.cbData = sizeof(tt); //数据大小
HWND sender = (HWND)effectiveWinId();
::SendMessage(hwnd,WM_COPYDATA,reinterpret_cast<WPARAM>(sender),reinterpret_cast<LPARAM>(©data));
}
2.接收方:
bool Receiver::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG *param = static_cast<MSG *>(message);
switch(param->message)
{
case WM_COPYDATA:
{
COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT *>(param->lParam);
if(cds->dwData == CUSTOM_TYPE)
{
struct test
{
QSting tq;
float tf;
int ti;
}*tt;
tt = (test*)cds->lpData;
QMessageBox::information(this,QStringLiteral("字符串为:"),QString(tr("%1").arg(tt->tq)));
*result = 1;
return true;
}
}
}
return QWidget::nativeEvent(eventType,message,result);
}
经过断点发现,在这个进程间通信程序中,int型数据和float型数据都是正常的,但是QSting型数据无法识别?请问各位大神们,这是怎么回事?怎么才能在进程间通信中传送含有QString型数据的结构体?
...全文
1386 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-01-23
  • 打赏
  • 举报
回复
百度搜“map 序列化”
TOBY110 2017-01-22
  • 打赏
  • 举报
回复
经过一段时间的研究,我发现赵4老师说的很有道理,我在结构体中用char型数组替代QString就能直接通过指针传递内存来达到效果。如果一定要在结构体中需要包含QString型数据,可以用序列化和反序列化的方法来传送,我也成功的实现了这个程序。 但是还有一个问题需要请教赵老师,QMap< int, struct >怎么序列化啊?key值是int型,value值是struct型,好像不能直接序列化???
赵4老师 2017-01-11
  • 打赏
  • 举报
回复
《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》
赵4老师 2017-01-11
  • 打赏
  • 举报
回复
类的实例是对象,不是一段内存,不适合直接拿指向它的指针开始的若干个字节传来传去。
TOBY110 2017-01-11
  • 打赏
  • 举报
回复
引用
请看源码: 1.发送方: void Sender::onSendMessage() { HWND hwnd = NULL; LPWSTR path = (LPWSTR)c_strTitle.utf16(); //path = L"SendMessage" hwnd = ::FindWindowW(NULL,path); if(::IsWindow(hwnd)) { struct test { QSting tq; float tf; int ti; }tt; tt.tf=3.14; tt.ti=5; tt.tq="abcd"; COPYDATASTRUCT copydata; copydata.dwData = CUSTOM_TYPE; //自定义用户号 copydata.lpData = &tt; //指向数据的指针 copydata.cbData = sizeof(tt); //数据大小 HWND sender = (HWND)effectiveWinId(); ::SendMessage(hwnd,WM_COPYDATA,reinterpret_cast<WPARAM>(sender),reinterpret_cast<LPARAM>(©data)); } 2.接收方: bool Receiver::nativeEvent(const QByteArray &eventType, void *message, long *result) { MSG *param = static_cast<MSG *>(message); switch(param->message) { case WM_COPYDATA: { COPYDATASTRUCT *cds = reinterpret_cast<COPYDATASTRUCT *>(param->lParam); if(cds->dwData == CUSTOM_TYPE) { struct test { QSting tq; float tf; int ti; }*tt; tt = (test*)cds->lpData; QMessageBox::information(this,QStringLiteral("字符串为:"),QString(tr("%1").arg(tt->tq))); *result = 1; return true; } } } return QWidget::nativeEvent(eventType,message,result); } 经过断点发现,在这个进程间通信程序中,int型数据和float型数据都是正常的,但是QSting型数据无法识别?请问各位大神们,这是怎么回事?怎么才能在进程间通信中传送含有QString型数据的结构体?
顶楼的程序我通过调试发现test结构体对象tt的内存地址0x22c628所对应的12个字节的数据里面并不包含QString tq的数据,而结构体成员变量tq的内存地址为0x405120,所以程序以test结构体对象tt的地址通过lpData传递给接收进程后,接收进程以地址0x22c628解析就解析不出来QString的数据。而float tf 和int ti的数据存储在0x22c628这片内存中,所以能解析出来。 各位大神们能给我解释一下为什么会出现这样的情况吗?怎么去解决这个问题? 非常感谢了!
赵4老师 2017-01-10
  • 打赏
  • 举报
回复
了解以下json,protobuf,xml
TOBY110 2017-01-10
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
https://www.baidu.com/s?wd=qstring序列化
如果仅仅是QString的序列化,那我知道怎么处理,但是含有Qstring成员的结构体的序列化呢? 网上是做一个类,将类序列化传送。 Student& Student::operator =(const Student &other) { this->name = other.name; this->age = other.age; } #ifndef QT_NO_DATASTREAM QDataStream& operator>>(QDataStream& in,Student& data) { in>>data.name>>data.age; return in; } QDataStream& operator<<(QDataStream& out,Student& data) { out<<data.name<<data.age; return out; } 但只能这样处理吗?能不能只传送结构体?我是个新手,有很多地方不是太理解,了解的也很片面,还请大神帮忙不厌其烦的解惑,谢谢了!
TOBY110 2017-01-10
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
类有专门的序列化反序列化功能。


大神你好,我查了一下序列化和反序列化的资料,用QDataStream来做?能给我简单的举个处理的例子吗?有例子我比较好理解点,谢谢啦!
TOBY110 2017-01-09
  • 打赏
  • 举报
回复
我刚学QT有些东西还不是太熟,能给个例子吗,具体怎么操作的?谢谢大神了
赵4老师 2017-01-09
  • 打赏
  • 举报
回复
类有专门的序列化反序列化功能。
sdghchj 2017-01-09
  • 打赏
  • 举报
回复
噢抱歉,没看到是WM_COPYDATA消息,QString内部有深层对象指针,而COPYDATA只是简单的bit拷贝,不即只会拷贝QString内部的指针值,而不再拷贝该指针指向的实际字符串,那么在另一个进程里该指针指向的当然不会是"abcd"。 通信还是用原始的c风格的字符数组,不要用QString、CString、std::string之类的东东。
sdghchj 2017-01-09
  • 打赏
  • 举报
回复
你确定是进程间通信?进程间能这样共享变量地址?

24,861

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧