请教大侠关于创建多线程遇到的问题
我使用createThread创建线程,调用格式如下:
m_Thread=CreateThread(NULL,0,PortReadThread,0,0,&dwTheardID)
dwThreadId为DWORD型,
PortReadThread为如下函数
DWORD CSerialPort::PortReadThread(LPVOID lpvoid)
{
}
为何在编译时会出现如下的问题:
'CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)'
谢谢!!!
问题点数:40、回复次数:11Top
1 楼cpmax()回复于 2004-09-04 07:31:25 得分 2
定义线程执行的函数不能为类的函数!
只能是全局的函数,如果一定要这样做的吧,可以定义该函数为该类的友元函数,加上关键字friend!
Top
2 楼ymirhu(玩转地球)回复于 2004-09-04 09:33:23 得分 0
这回我将PortReadThread(LPVOID lpvoid)定义成全局变量。在cserialport类中也将其加为友元函数,其它没变:
if (!m_Thread=CreateThread(NULL,0,PortReadThread,0,0,&dwTheardID))
{};
DWORD PortReadThread(LPVOID lpvoid)
{};
PortReadThread()显示的为全局函数
可编译时还是出现
CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)'
而且,在PortReadThread()里面使用的CserialPort的变量变成没有声明的变量?
还望大侠继续指导!呵呵,谢谢!
Top
3 楼NeverMind8086(不要紧)回复于 2004-09-04 10:36:09 得分 2
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PortReadThread, 0, 0, &dwThreadID)Top
4 楼yaozijian110()回复于 2004-09-04 11:15:47 得分 25
线程函数必须是全局函数或者类的静态函数,而且必须是以_stdcall为调用方式的,所以
DWORD CSerialPort::PortReadThread(LPVOID lpvoid)
的定义应该是:
1 如果把它作为全局函数:
DWORD CALLBACK ProtReadThread(LPVOID lpvoid);
创建线程的语句是:
CreateThread(NULL, 0, PortReadThread, 0, 0, &dwThreadID);
不需要LPTHREAD_START_ROUTINE的。
2 如果把它作为CSerialPort类的静态函数:
class CSerialPort
{ .......
public:
DWORD CALLBACK ProtReadThread(LPVOID lpvoid);
......
}
这时候创建线程的语句应该是:
CreateThread(NULL, 0, CSerialPort::PortReadThread, 0, 0, &dwThreadID);
Top
5 楼ymirhu(玩转地球)回复于 2004-09-04 11:44:26 得分 0
同意 yaozijian110() 兄弟的观点,所以将它改成CSerialPort的静态函数,但编译时出现的还是如下错误:
error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)'
不解,难道我在别的地方出现别的错误了。
还望继续指点一二!!谢谢非常!!Top
6 楼baoyuhua(榕树)回复于 2004-09-04 11:54:26 得分 2
我认为线程函数似乎不可以作为类的静态函数Top
7 楼ymirhu(玩转地球)回复于 2004-09-04 12:24:47 得分 0
刚才我将线程函数改为定义全局函数了!
定义如下:
DWORD WINAPI PortReadThread(LPVOID lpvoid);
为了能够使用CSerialPort的变量,我在用CreateThread中使用了this指针,使用如下:
CreateThread(NULL,0,PortReadThread,this,0,&dwTheardID);
在PortReadThread的定义里,我重新定义一个串口类变量,让他接过this的指针,
CSerialPort *pThread=(CSerialPort *)lpvoid;
结果,编译通过了。至于究竟能不能使用CSerialPort的变量,还有待测试!
感谢大家的帮忙!谢谢!
前面的问题还些没有获得解决,我得编译是通过了,还希望有更多的人能给我指点!
以后看到这个话题的人还希望能继续回答!谢谢!我会热心期待你们的解答!
Top
8 楼yaozijian110()回复于 2004-09-04 14:24:25 得分 0
至于究竟能不能使用CSerialPort的变量,还有待测试!
--------------------------------------------------
可以使用CSerialPort的变量的。CSerialPort是MFC中的类吗?如果是的话,可能有些变量不能使用,因为MFC里面有一套句柄映射的东西(我也不太清楚,反正我传MFC的对话框类的指针进去的时候,有些变量就不能用了)。
Top
9 楼yaozijian110()回复于 2004-09-04 14:31:25 得分 0
线程函数一定可以是类的静态函数的,请看下面的例子:
#include <iostream.h>
#include <windows.h>
class CThread
{
public:
static DWORD CALLBACK ThreadProc(LPVOID p)
{
for(int i = 0; i < 100; i++ )
cout << i << endl;
cout<<endl;
return 0;
}
};
void main()
{
HANDLE hThread;
DWORD dwID;
hThread = CreateThread(NULL,0,CThread::ThreadProc,NULL,0,&dwID);
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
cout << "OK"<<endl;
}
至于你的程序出现这样的错误:
error C2664: 'CreateThread' : cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long (__stdcall *)(void *)'
我想最大的可能是没有加CALLBACK修饰那个作为线程函数的类的静态函数。
Top
10 楼xlt123(杀了你好吗)回复于 2004-09-04 14:36:15 得分 9
可以定义成静态函数,
不过你得定义成 static DWORD WINAPI PortReadThread(LPVOID);
WINAPI 也就是 _stdcall
这样,你在线程函数你就可以访问类的所有变量,
你如果定义成全局函数,就只能访问类的public变量.
当然,你如果不厌其烦的为每个非public变量写一对
public的set/get函数也可以,呵呵.Top
11 楼ymirhu(玩转地球)回复于 2004-09-04 15:26:42 得分 0
哦!对这个问题终于有了个全面的认识!
感谢这么多热心的朋友!
明天我就把这给结题了!
再次感谢!Top




