大家好,在基于对话框的一个MFC程序中,我添加了一个
UINT ThreadFunc(LPVOID pParam);
也添加了相应的头文件等等。
在我定义的线程函数中我调用了自定义的一个函数,但是编译的时候这个函数名一直是undeclared identifier。
好像这个涉及到线程间通信,刚学多线程,请大家指教,具体一些。不胜感激。
UINT ThreadFunc(LPVOID pParam);
也添加了相应的头文件等等。
在我定义的线程函数中我调用了自定义的一个函数,但是编译的时候这个函数名一直是undeclared identifier。
好像这个涉及到线程间通信,刚学多线程,请大家指教,具体一些。不胜感激。
好像这个涉及到线程间通信,刚学多线程,请大家指教,具体一些。不胜感激。
===========
编译出现问题,这个和线程间通信没有关系,你多贴点代码出来看看。
在对话框头文件中声明了:
void DrawPicToHDC(IplImage *img, UINT ID);
IplImage *img1;
IplImage *img2;
CCameraDS camera1;
CCameraDS camera2;
static UINT ThreadProc1(LPVOID pParam);
static UINT ThreadProc2(LPVOID pParam);在对话框实现文件中定义了:
void CMy1Dlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}然后在线程函数中调用函数DrawPicToHDC(IplImage *img, UINT ID)
UINT ThreadProc1(LPVOID pParam)
{
//打开第一个摄像头
CCameraDS camera1; if(! camera1.OpenCamera(0)) //第一个摄像头
{
fprintf(stderr, "Can not open camera.\n");
}
IplImage *img1=0;
while(1)
{
//获取一帧
IplImage *img1 = camera1.QueryFrame();
DrawPicToHDC(img1, IDC_STATIC);
if (cvWaitKey(20) == 'q')
break;
}
camera1.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头 return 0;
}UINT ThreadProc2(LPVOID pParam)
{
////打开第二个摄像头
CCameraDS camera2;//打开第二个摄像头
if(! camera2.OpenCamera(2)) //这里选择2是因为本程序运行后0和1都指向同一个摄像头
{
fprintf(stderr, "Can not open camera.\n");
}IplImage *img2=0;while(1)
{//获取一帧
IplImage *img2 = camera2.QueryFrame(); //采用两个完全相同的摄像头时,程序在此崩溃
DrawPicToHDC(img2, IDC_STATIC1);
if (cvWaitKey(20) == 'q')
break;
}
camera2.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头 return 0;
}void CMy1Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
HWND hwnd=GetSafeHwnd();
AfxBeginThread(ThreadProc1,hwnd,THREAD_PRIORITY_NORMAL);
}
void CMy1Dlg::OnButton2()
{
// TODO: Add your control notification handler code here
HWND hwnd=GetSafeHwnd();
AfxBeginThread(ThreadProc2,hwnd,THREAD_PRIORITY_NORMAL);
}编译出错:'DrawPicToHDC' : undeclared identifier
请问这是什么原因呢
=====================
你的线程函数好像不是类的成员函数啊,当然不能调用类成员函数DrawPicToHDC了。
然后改成UINT CMy1Dlg::ThreadProc1(LPVOID pParam)
UINT CMy1Dlg::ThreadProc2(LPVOID pParam)这样就行啦
可是又有新问题了:
f:\多线程1\多线程1dlg.cpp(213) : error C2352: 'CMy1Dlg::DrawPicToHDC' : illegal call of non-static member function
f:\多线程1\多线程1dlg.h(27) : see declaration of 'DrawPicToHDC'
f:\多线程1\多线程1dlg.cpp(240) : error C2352: 'CMy1Dlg::DrawPicToHDC' : illegal call of non-static member function
f:\多线程1\多线程1dlg.h(27) : see declaration of 'DrawPicToHDC'声明时改为 static void DrawPicToHDC(IplImage *img, UINT ID);也不对
然后改成UINT CMy1Dlg::ThreadProc1(LPVOID pParam)
UINT CMy1Dlg::ThreadProc2(LPVOID pParam)这样就行啦
可是又有新问题了:
f:\多线程1\多线程1dlg.cpp(213) : error C2352: 'CMy1Dlg::DrawPicToHDC' : illegal call of non-static member function
f:\多线程1\多线程1dlg.h(27) : see declaration of 'DrawPicToHDC'
f:\多线程1\多线程1dlg.cpp(240) : error C2352: 'CMy1Dlg::DrawPicToHDC' : illegal call of non-static member function
f:\多线程1\多线程1dlg.h(27) : see declaration of 'DrawPicToHDC'声明时改为 static void DrawPicToHDC(IplImage *img, UINT ID);也不对
==========
我上面不是说了吗,线程函数改成成员函数之后,静态函数中不能引用非静态成员,所以还是不行。
你可以在线程函数中向对话框发自定义消息,让对话框在响应自定义消息时自己去调用那个函数。
CMy1Dlg a;
a.DrawPicToHDC(img1, IDC_STATIC);呢
不过这样编译时通过了,执行时又出现问题了···
CMy1Dlg a;
a.DrawPicToHDC(img1, IDC_STATIC);呢
不过这样编译时通过了,执行时又出现问题了···
========
这样编译当然没事,但是此时CMy1Dlg a这个对象和你的对话框就没有关系了。执行时当然不行了。
在对话框头文件中定义自定义消息const WM_USRMSG=WM_USER+100;//定义用户消息
声明自定义消息响应函数:afx_msg void DrawPicToHDC(IplImage *img, UINT ID);
在对话框实现文件中自定义映射:ON_MESSAGE(WM_USRMSG,DrawPicToHDC)
自定义消息响应函数:
void CMy1Dlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}
定义线程函数:
UINT ThreadProc1(LPVOID pParam)
{
//打开第一个摄像头
CCameraDS camera1; if(! camera1.OpenCamera(0)) //第一个摄像头
{
fprintf(stderr, "Can not open camera.\n");
}
IplImage *img1=0;
while(1)
{
//获取一帧
IplImage *img1 = camera1.QueryFrame();
DrawPicToHDC(img1, IDC_STATIC);
if (cvWaitKey(20) == 'q')
break;
}
camera1.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头 return 0;
}UINT ThreadProc2(LPVOID pParam)
{
////打开第二个摄像头
CCameraDS camera2;//打开第二个摄像头
if(! camera2.OpenCamera(2)) //这里选择2是因为本程序运行后0和1都指向同一个摄像头
{
fprintf(stderr, "Can not open camera.\n");
}IplImage *img2=0;while(1)
{//获取一帧
IplImage *img2 = camera2.QueryFrame(); //采用两个完全相同的摄像头时,程序在此崩溃
DrawPicToHDC(img2, IDC_STATIC1);
if (cvWaitKey(20) == 'q')
break;
}
camera2.CloseCamera(); //可不调用此函数,CCameraDS析构时会自动关闭摄像头 return 0;
}void CMy1Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
HWND hwnd=GetSafeHwnd();
AfxBeginThread(ThreadProc1,hwnd,THREAD_PRIORITY_NORMAL);
}
void CMy1Dlg::OnButton2()
{
// TODO: Add your control notification handler code here
HWND hwnd=GetSafeHwnd();
AfxBeginThread(ThreadProc2,hwnd,THREAD_PRIORITY_NORMAL);
}
编译后还是说'DrawPicToHDC' : undeclared identifier,怎么会这样呢?
在对话框头文件中定义自定义消息const WM_USRMSG=WM_USER+100;//定义用户消息
声明自定义消息响应函数:afx_msg void DrawPicToHDC(IplImage *img, UINT ID);
在对话框实现文件中自定义映射:ON_MESSAGE(WM_USRMSG,DrawPicToHDC)
==========
后面的没看,有几个问题:
定义自定义一般的写法是:#define WM_USERMSG WM_USER+100
自定义消息响应函数afx_msg void DrawPicToHDC(IplImage *img, UINT ID);这样写是不行的,一般定义成:afx_msg void MyMsgProc(WPARAM wParam, LPARAM lParam);
你可以在MyMsgProc中调用DrawPicToHDC,而不是用DrawPicToHDC作为消息的处理函数。
afx_msg LRESULT OnMessage(WPARAM wParam, LPARAM lParam);
在对话框实现文件中自定义消息映射:
ON_MESSAGE(WM_USERMSG, OnMessage)
自定义消息响应函数:
LRESULT CMy1Dlg::OnMessage(WPARAM wParam, LPARAM lParam)
{
DrawPicToHDC(IplImage *img, UINT ID);
return 0;
}
定义线程函数:
UINT ThreadProc1(LPVOID lpParam)
{…
HWND hWnd = (HWND)lpParam;
SendMessage(hWnd, UM_MESSAGE, 0, 0);
…
return 0;}
UINT ThreadProc2(LPVOID lpParam)
{…
HWND hWnd = (HWND)lpParam;
SendMessage(hWnd, UM_MESSAGE, 0, 0);
…
return 0;}
还是不对:f: \多线程1\多线程1dlg.cpp(198) : error C2065: 'img' : undeclared identifier
f: \多线程1\多线程1dlg.cpp(198) : error C2275: 'IplImage' : illegal use of this type as an expression
e:\opencv\cxcore\include\cxtypes.h(393) : see declaration of 'IplImage'
f: \多线程1\多线程1dlg.cpp(198) : error C2275: 'UINT' : illegal use of this type as an expression
e:\vc98\include\windef.h(162) : see declaration of 'UINT'
f:\多线程1\多线程1dlg.cpp(198) : error C2146: syntax error : missing ')' before identifier 'ID'
f:\多线程1\多线程1dlg.cpp(198) : error C2059: syntax error : ')'
f: \多线程1\多线程1dlg.cpp(220) : error C2065: 'UM_MESSAGE' : undeclared identifier
============
有这样调用函数的吗?调用函数还写参数类型啊?应该是这样吧:DrawPicToHDC(img, ID);: \多线程1\多线程1dlg.cpp(220) : error C2065: 'UM_MESSAGE' : undeclared identifier
================
这个错误明显是拼写错误啊,应该是WM_MESSAGE
LRESULT CMy1Dlg::OnMessage(WPARAM wParam, LPARAM lParam)
{
IplImage *img=(IplImage *)wParam;
UINT ID=UINT(lParam);
DrawPicToHDC(img,ID);
return 0;
}SendMessage(hWnd, WM_USERMSG, img1, IDC_STATIC);发生错误:
c:\documents and settings\administrator\桌面\多线程1\多线程1dlg.cpp(224) : error C2664: 'SendMessageA' : cannot convert parameter 3 from 'struct _IplImage *' to 'unsigned int'
SendMessage(hWnd, WM_USERMSG, (WPARAM)img1, (LPARAM)IDC_STATIC_PIC);
SendMessage(hWnd,WM_USERMSG, (WPARAM)img2, (LPARAM)IDC_STATIC_PIC1); 编译还是出错:
多线程1Dlg.obj : error LNK2001: unresolved external symbol "public: static unsigned int __cdecl CMy1Dlg::ThreadProc1(void *)" (?ThreadProc1@CMy1Dlg@@SAIPAX@Z)
多线程1Dlg.obj : error LNK2001: unresolved external symbol "public: static unsigned int __cdecl CMy1Dlg::ThreadProc2(void *)" (?ThreadProc2@CMy1Dlg@@SAIPAX@Z)
Debug/多线程1.exe : fatal error LNK1120: 2 unresolved externals
多线程1Dlg.obj : error LNK2001: unresolved external symbol "public: static unsigned int __cdecl CMy1Dlg::ThreadProc1(void *)" (?ThreadProc1@CMy1Dlg@@SAIPAX@Z)
多线程1Dlg.obj : error LNK2001: unresolved external symbol "public: static unsigned int __cdecl CMy1Dlg::ThreadProc2(void *)" (?ThreadProc2@CMy1Dlg@@SAIPAX@Z)
Debug/多线程1.exe : fatal error LNK1120: 2 unresolved externals
=================
这个估计是以前将线程函数当作类的成员函数时留下H文件中函数声明没有删除造成的,将H文件中线程函数声明去掉就行了。
IplImage *img;
UINT ID;
void DrawPicToHDC(IplImage *img, UINT ID);
定义:
void CMyDlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CDC *pDC = GetDlgItem(ID)->GetDC();
HDC hDC= pDC->GetSafeHdc();
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}
是什么问题呢
CWnd *p = GetDlgItem(ID);
if (p != NULL)
p->...
GetDlgItem(ID)->GetClientRect(&rect);
============
最大的可以是上面两句中的GetDlgItem(ID)得到的是指针是NULL,你在调用这两个之前必须要保证相关的控件必须要实际存在
UINT ThreadFunc(LPVOID pParam);这个样子啊。
过程函数是回调函数,有Windows调用,所以应该是标准风格 _stdcall
DWORD WINAPI ThreadProc(
LPVOID lpParameter // thread data
);
void CMyDlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CWnd *p = GetDlgItem(ID); //得到指针
if(p!=NULL)//若指针不为零
CDC *pDC =p->GetDC();
HDC hDC=pDC->GetSafeHdc();
CRect rect;
p->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
ReleaseDC(pDC);
}
还是不对
:\多线程重写—该内存不能为read\多线程重写dlg.cpp(201) : error C2065: 'pDC' : undeclared identifier
f:\多线程重写—该内存不能为read\多线程重写dlg.cpp(201) : error C2227: left of '->GetSafeHdc' must point to class/struct/union
执行 cl.exe 时出错.
if(p!=NULL)//若指针不为零
{
CDC *pDC =p->GetDC();
if (pDC != NULL)
{
HDC hDC=pDC->GetSafeHdc();
CRect rect;
p->GetClientRect(&rect);
CvvImage cimg; cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect); p->ReleaseDC(pDC);
}
}
我在CPP文件里定义了一个全局HWND 类型的变量,用于存储对话框句柄 HWND hWnd;
线程函数中:
SendMessage((HWND)lpParam, WM_USERMSG, (WPARAM)img1, (LPARAM)IDC_STATIC_PIC);
SendMessage((HWND)lpParam, WM_USERMSG, (WPARAM)img2, (LPARAM)IDC_STATIC_PIC1);
按钮的函数:
AfxBeginThread(ThreadProc1,hWnd,THREAD_PRIORITY_NORMAL);
AfxBeginThread(ThreadProc2,hWnd,THREAD_PRIORITY_NORMAL);
是不是跟我定义的函数的句柄不一致呢
void CMyDlg::DrawPicToHDC(IplImage *img, UINT ID)
{
CWnd *pWnd = GetDlgItem(ID); //得到指针
if(pWnd!=NULL)//若指针不为零
{
CDC *pDC =pWnd->GetDC();
if (pDC != NULL)
{
HDC hDC=pDC->GetSafeHdc();
CRect rect;
pWnd->GetClientRect(&rect);
CvvImage cimg;
cimg.CopyOf(img);
cimg.DrawToHDC(hDC,&rect);
pWnd->ReleaseDC(pDC);
}
}
}