急,,,为什么PostMessage发送结构体会乱码//结构体struct Student{char Name[10]int age}//发送端@bcb工
急,,,为什么PostMessage发送结构体会乱码
//结构体 struct Student { char Name[10]; int age; }; //发送端@bcb工程 Student *stu =new Student; strcpy(stu->Name,"date"); stu->age = 18; PostMessage(FindWindow(NULL,"Receive"),WM_SEND,0,(LPARAM)&stu); //已发送成功 //接收端@VS MFC工程 LRESULT CReceiveDlg::OnMyMessage(WPARAM wParam, LPARAM lParam) { // TODO: 处理用户自定义消息 Student* stu=(Student *)lParam; int n = stu->age; //数据不对 char nam[10]; strcpy(nam, stu->Name); //乱码 delete stu; return 0; }如上,PostMessage给其他程序发送结构体接收到的数据会乱码,SendMessage的WM_COPYDATA不考虑,效率偏低,也不考虑共享内存的方法,只想通过PostMessage给其他程序发送结构体。请问各位有什么解决方法呢?
[最优解释] 而且不同进程之间最好用共享内存.
[其他解释] PostMessage(FindWindow(NULL,"Receive"),WM_SEND,0,(LPARAM)stu);
把&去掉
[其他解释] FILE_MAP_WRITE,0,0,0);
if(pv!=NULL){
memcpy(pv,ss.str().c_str(),sz);
memset((char*)pv+sz,0,256-sz);
UnmapViewOfFile(pv);
}
//send to target process
DWORD idProcess;
GetWindowThreadProcessId(hwnd,&idProcess);
HANDLE hProcess= OpenProcess(PROCESS_DUP_HANDLE,FALSE,idProcess);
HANDLE hDup=0;
DuplicateHandle(GetCurrentProcess(),hFile,hProcess,&hDup,NULL,FALSE,DUPLICATE_SAME_ACCESS);
PostMessage(hwnd,WM_MSG_SEND,0,(LPARAM)hDup);
CloseHandle(hFile);
/*
if(pStream->Write(ss.str().c_str(),ss.str().size(),NULL)!=S_OK){
cout<<"stream write fail"<<endl;
}
HGLOBAL hgb=NULL;
//PostMessage(hwnd,WM_MSG_SEND,0,(LPARAM)hgb);
GetHGlobalFromStream(pStream,&hgb);
pStream->Release();
ULONG sz=GlobalSize(hgb);
*/
cout<<"item posted, bytes ="<<sz<<endl<<endl;
CoUninitialize();
}else{
break;
}
} while (1);
return 0;
}
接收端:
#include <windows.h> #include <stdio.h> #include <sstream> using namespace std; struct Stu{ char name[10]; int m_nAge; }; istream& operator>>(istream& is,Stu& x) { is>>x.name; is>>x.m_nAge; return is; } ostream& operator<<(ostream& os,Stu& x) { os<<x.name; os<<x.m_nAge; return os; } #define WM_MSG_SEND WM_USER+125 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("RecvData") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW [其他解释] 检查一下工程设置中的结构体字节对齐问题:[其他解释] 楼主没有调试的习惯,只看结果。如果调试以下,申请的时候看看stu,消息来的时候,在看一下参数,不至于看不到问题所在[其他解释] Student *stu =new Student; 改成student stu;看看[其他解释] 先谢谢楼上各位提供的意见哈,几天没上来看帖子,发现热心的朋友还是挺多的…… 闲话不多说了……
引用: 做了一个进程间发送接收例程 发送端: C/C++ code? 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828…… @mcmcmc 谢谢mcmcmc,朋友你的测试程序是同一编译器吧?我的不是哦,发送端是C++Builder程序,接收端是VS的MFC程序.
引用: 引用: 引用:跨进程还能用POSTMessage穿地址么?! @ hushoubo 跨进程传地址无效的,那POSTMessage可不可以在进程间传数据呢?我的程序是这样的,发送端偶尔会给接收端发送一个消息,但是不需要回复收到消息的确认,只要把它丢在消息队列了就行了,这样可以减少延时,之前用的SendMessage+WM…… @sugar13 谢谢sugar13,我正在考虑用Postmessage+剪贴板通信的方法,基本能实现。至于你说的用户也用剪贴板的话,数据会不会被破坏.. 这个可以放心,我的界面程序是全屏仅限触摸屏使用的,其他用户用不了复制粘贴的操作。
引用: 检查一下工程设置中的结构体字节对齐问题: @shine159111 谢谢shine159111 结构体的字节对齐也是个值得考虑的问题,这个我会抽空测试下。
引用: 是否是接收端和服务端的字节对齐问题导致的。 两个进程都使用 #pragam pack(1) 定义结构体 #pragma pack() 试试 @ bsnry 谢谢bsnry 你的建议,我测试一下再回帖哈,谢谢。
引用: Student* stu=(Student *)lParam; 你这么接收是不是有点问题 能不能先new一个空间出来,然后强制转换为Student,然后再来赋值 这样直接接收,在进程中可能会有问题 @GLSC_CENA 谢谢GLSC_CENA 接收端也要new一块空间?我刚刚试了一下,传过来的是两个地址哦。
引用: 这么多人都没发现嘛, 跨进程的发送指针对嘛? 无论sendmessage,postmessae,都不对啊? 否则就多一种进程通信的方式了:发送消息。 所谓发送消息,根本就不能够发送数据出去的。 引用: 做了一个进程间发送接收例程 发送端: C/C++ code?123456789101112131415161718192021222…… @liulin2025 谢谢liulin2025 众人皆醉你独醒哦,所以我在考虑用别的通讯方式,当然啦尽可能不Postmessage的特性也用上。
引用: WM_COPYDATA @VisualEleven 谢谢十一版主,WM_COPYDATA仅限Sendmessage哦,那个效率低我放弃了。
引用: 楼主没有调试的习惯,只看结果。如果调试以下,申请的时候看看stu,消息来的时候,在看一下参数,不至于看不到问题所在 @pengyw 谢谢pengyw 朋友你可以看我11 16楼的回帖啦,我有调试的。tiger9991 朋友10楼的建议把&去掉其实是可行的,不过限于同一编译器同一工程里。
这几天工作忙,可能不能及时回帖,迟些问题解决了再结贴哈,衷心感谢楼上各位的热心帮助!
[其他解释] FILE_MAP_READ,0,0,0);
char* buf=(char*)pv;
stringstream ss(buf);
ss>>item;
char str[30]={0};
sprintf(str,"SZ=%d,name=%s,age=%d",strlen(buf),item.name,item.m_nAge);
MessageBox(NULL,str,"recv",MB_OK);
CloseHandle(hFile);
}
return 0;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
效果:
------其他解决方案--------------------
可能是‘对齐’问题 试试 1字节 对齐
[其他解释] 引用: 引用:跨进程还能用POSTMessage穿地址么?! @ hushoubo 跨进程传地址无效的,那POSTMessage可不可以在进程间传数据呢?我的程序是这样的,发送端偶尔会给接收端发送一个消息,但是不需要回复收到消息的确认,只要把它丢在消息队列了就行了,这样可以减少延时,之前用的SendMessage+WM_COPYDATA的方式…… 用剪贴板通信的话,万一赶上用户也用剪贴板的话,会不会被破坏..
[其他解释] 跨进程还能用POSTMessage穿地址么?!
[其他解释] CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("recv data"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
200, 200,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MSG_SEND:
{
Stu item;
HANDLE hFile=(HANDLE)lParam;
PVOID pv=MapViewOfFile(hFile,FILE_MAP_WRITE
[其他解释] 是否是接收端和服务端的字节对齐问题导致的。
两个进程都使用
#pragam pack(1)
定义结构体
#pragma pack()
试试
[其他解释] Student* stu=(Student *)lParam;
你这么接收是不是有点问题
能不能先new一个空间出来,然后强制转换为Student,然后再来赋值
这样直接接收,在进程中可能会有问题
[其他解释] WM_COPYDATA
[其他解释] 不同编译器,二进制解释方法不同,做成xml数据流来发吧.
[其他解释] 引用: 不同编译器,二进制解释方法不同,做成xml数据流来发吧. 我试试,谢谢!
[其他解释] 该回复于2012-11-24 09:57:59被管理员删除
[其他解释] 不同的C++编译器对于类的二进制构造是不同的,比如有些exe调用其他编译器做的dll(class)会出乱子,只有c语言才是规范的
而且内存地址只在本进程中有效,跨了进程一点意义也没有.
[其他解释] 引用:
不同的C++编译器对于类的二进制构造是不同的,比如有些exe调用其他编译器做的dll(class)会出乱子,只有c语言才是规范的 而且内存地址只在本进程中有效,跨了进程一点意义也没有. 嗯嗯,我继续琢磨一下,实在不行只能用别的方法了,谢谢
[其他解释] 用SendMessage看看
[其他解释] 引用: 用SendMessage看看 不好意思呢,我现在用的就是SendMessage,不过效率实在不行,有延时
[其他解释] 引用: PostMessage(FindWindow(NULL,"Receive"),WM_SEND,0,(LPARAM)stu); 把&去掉 这个我也试过了的,当执行到接收消息程序的int n = stu->age;赋值语句是程序会报错
[其他解释] 引用: 可能是‘对齐’问题 试试 1字节 对齐 朋友你说的一字节对齐是不是这样定义一个结构体
struct test { char Name[1]; char Sex[1]; };这样也是乱码哦。
[其他解释] windows采用的是进程独立地址空间制度,Post,Send之流只能传递DWORD,无法将整个结构穿过去.
好比上海有个电话62221111,北京也有一个电话62221111,号码一样,用户完全不同.
还是共享内存比较靠谱.
[其他解释] 最后一个方法了,你把stu放全局,保证其生命周期。
再用这个
PostMessage(FindWindow(NULL,"Receive"),WM_SEND,0,(LPARAM)stu);
[其他解释] 引用: 最后一个方法了,你把stu放全局,保证其生命周期。 再用这个 PostMessage(FindWindow(NULL,"Receive"),WM_SEND,0,(LPARAM)stu); @tiger9991
按你的建议,跟踪了一下,发送前的stu的地址,和接收到的lParam地址一致,但是没有数据了呢
[其他解释] 引用: 跨进程还能用POSTMessage穿地址么?! @ hushoubo 跨进程传地址无效的,那POSTMessage可不可以在进程间传数据呢?我的程序是这样的,发送端偶尔会给接收端发送一个消息,但是不需要回复收到消息的确认,只要把它丢在消息队列了就行了,这样可以减少延时,之前用的SendMessage+WM_COPYDATA的方式有点慢,所以考虑用POSTMessage。
进程间通讯还有剪贴板,管道,邮槽等。
[其他解释] 引用: #pragma pack(push, 1) struct Student { char Name[10]; int age; }; #pragma pack(pop) 进程间 用 WM_COPYDATA 谢谢,可是POSTMessage发送不了WM_COPYDATA消息的哦
引述资料书上的:
你必须使用 SendMessage() 传送 WM_COPYDATA , 不能够使用PostMessage() 或任何其他变种函数如 PostThreadMessage() 之流。这是因为系统必须管理用以传递数据的缓冲区的生命期。如果你使用PostMessage(),数据缓冲区会在接收端(线程)有机会处理该数据之前,被系统清除并摧毁。
[其他解释] #pragma pack(push, 1)
struct Student { char Name[10]; int age; };
#pragma pack(pop)
进程间 用 WM_COPYDATA
[其他解释] 做了一个进程间发送接收例程
发送端:
#include <windows.h> #include <iostream> #include <string> #include <sstream> using namespace std; struct Stu{ char name[10]; int m_nAge; }; istream& operator>>(istream& is,Stu& x) { is>>x.name; is>>x.m_nAge; return is; } ostream& operator<<(ostream& os,Stu& x) { os<<x.name; os<<" "; os<<x.m_nAge; return os; } #define WM_MSG_SEND WM_USER+125 int main(int, char **, char **) { Stu item; string strcmd; do { cout<<"enter name:"; cin>>item.name; cout<<"enter age:"; cin>>item.m_nAge; cout<<"enter s to send, e to exit: "; cin>>strcmd; if(strcmd=="s"){ //post message HWND hwnd=FindWindow(NULL,TEXT("recv data")); if(hwnd==NULL){ cout<<"can't find target recv window!"<<endl<<endl; continue; } stringstream ss; ss<<item; size_t sz=ss.str().size(); HANDLE hFile=CreateFileMapping(INVALID_HANDLE_VALUE,NULL, PAGE_READWRITE,0,256,NULL); //write data PVOID pv=MapViewOfFile(hFile,FILE_MAP_READ[其他解释] postmessage 可以送 2*4 个字节的值。 看看 能不能分2次 post 出去 student 14 个 字节[其他解释] 这么多人都没发现嘛, 跨进程的发送指针对嘛? 无论sendmessage,postmessae,都不对啊? 否则就多一种进程通信的方式了:发送消息。 所谓发送消息,根本就不能够发送数据出去的。
引用: 做了一个进程间发送接收例程 发送端: C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182…… [其他解释] PostMessage保证不了,数据的有效性。用SendMessage