对话框工程中,
为什么我在
BOOL CMain::OnInitDialog() 
中这样写:
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)InitSQL,(void*)0,NULL,&nThreadID);
总出错?
UINT CMain::InitSQL(LPVOID lpVoid)
{
...
}错误信息:
Main.cpp(103):error C2440:'type cast':cannot convert from '' to 'unsigned long (__stdcall)(void *)'
None of the functions with this name in scope match the target type
再者,如果我要把一个CEdit型的变量传给InitSQL的话,在CreateThread中的那个参数应该怎么写?

解决方案 »

  1.   

    你定义的InitSQL函数应该是CMain的静态函数或者是全局函数!
    如果是静态回调函数:
    class CMain
    {
       ...
       CALLBACK static UINT InitSQL(LPVOID lpVoid);
       ...
    }
    如果是全局函数:
    UINT InitSQL(LPVOID lpVoid)
    {
    }如果要把一个CEdit型的变量传给InitSQL的话,应该传CEdit的指针,这样写:
    (假设pEdit是指向CEdit的指针)
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)InitSQL,(void*)pEdit,NULL,&nThreadID);
    在线程函数中可以这样使用:
    UINT InitSQL(LPVOID lpVoid)
    {
       CEdit* pEdit = (CEdit*)lpVoid;
       ...
    }
      

  2.   

    我像你那样定义线程函数出错:
    class main:public CDialog
    {
       ...
       CALLBACK static UINT InitSQL(LPVOID lpVoid);
       ...
    }错误信息:
    warning C4518:'static':storage-class or type specifier(s) unexpected here;ignored
    warning C4230:anachronism used:modifiers/qualifiers interspersed,qualifier ignored
    error C2146:syntax error : missing ';' before identifier 'InitSQL'
    warning C4229:anachronism used:modifiers on data are ignored后我把它改为全局可以了,不过,还没有得到完全测试
      

  3.   

    上面不好意思,搞反个了,应该是
    static UINT CALLBACK InitSQL(LPVOID lpVoid);
      

  4.   

    我按照那个全局方法写,
    把this传给线程,但在线程里:
    UINT InitSQL(LPVOID lpVoid)
    {
    CMain* pMain=(CMain*)lpVoid;
    try
    {
    pMain->pConn->Open((_bstr_t)strconn,TEXT(struser),TEXT(strpw),adModeUnknown);
    ...
    时,pMain->pConn->Open这一句出错,说是无效指针!!!
    pConn是在CMain里定义的一个变量:
    _ConnectionPtr pConn;
      

  5.   

    后来,又改成
    static UINT CALLBACK InitSQL(LPVOID lpVoid);
    在实现里:
    UINT CALLBACK CMain::InitSQL(LPVOID lpVoid)
    {
    CMain* pMain=(CMain*)lpVoid;
    try
    {
    ...
    依然说是无效指针!(在实现函数的前边不能加static,如果加上去的话,是出错,所以我把这里的static删去了)
    是这样调用的:
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)InitSQL,(void*)this,NULL,&nThreadID);
      

  6.   

    应该是
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CMain::InitSQL,(void*)this,NULL,&nThreadID);
      

  7.   

    还是不行啊,有关代码:
    ...
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CMain::InitSQL,(void*)this,NULL,&nThreadID); return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
    }UINT CALLBACK CMain::InitSQL(LPVOID lpVoid)
    {
    CMain* pMain=(CMain*)lpVoid;
    try
    {
    pMain->pConn->Open((_bstr_t)strconn,TEXT(struser),TEXT(strpw),adModeUnknown);//这一句出错,无效指针 CString strsql="select * from storage order by prod_name,prod_spec";
    //_ConnectionPtr pConn;
    pMain->pRec->Open(_variant_t(strsql),_variant_t((IDispatch*)pMain->pConn,true),adOpenStatic,adLockOptimistic,adCmdUnknown);
    //pRec->Open((LPCTSTR)strsql,(LPCTSTR)strconn,adOpenStatic,adLockOptimistic,adCmdUnknown);
    pMain->m_btnadd.EnableWindow(true);
    pMain->m_btnlook.EnableWindow(true);
    }
    catch(_com_error e)
    {
    ::MessageBox(pMain->m_hWnd,e.ErrorMessage(),TEXT("错误01"),MB_ICONSTOP);
    }
    pMain->m_btnexit.EnableWindow(true); return 0;
    }
      

  8.   

    如果是在同一个类中处理,不用传this指针了!
    把下面的pMain改成this就可以了!
    UINT CALLBACK CMain::InitSQL(LPVOID lpVoid)
    {
    try
    {
    pMain->pConn->Open((_bstr_t)strconn,TEXT(struser),TEXT(strpw),adModeUnknown);//这一句出错,无效指针 CString strsql="select * from storage order by prod_name,prod_spec";
    //_ConnectionPtr pConn;
    pMain->pRec->Open(_variant_t(strsql),_variant_t((IDispatch*)pMain->pConn,true),adOpenStatic,adLockOptimistic,adCmdUnknown);
    //pRec->Open((LPCTSTR)strsql,(LPCTSTR)strconn,adOpenStatic,adLockOptimistic,adCmdUnknown);
    pMain->m_btnadd.EnableWindow(true);
    pMain->m_btnlook.EnableWindow(true);
    }
    catch(_com_error e)
    {
    ::MessageBox(pMain->m_hWnd,e.ErrorMessage(),TEXT("错误01"),MB_ICONSTOP);
    }
    pMain->m_btnexit.EnableWindow(true); return 0;
    }
      

  9.   

    我只是演示以下那个现程的调用
    #include <iostream.h>
    #include <windows.h>
    class myclass
    {
    private:
    static int num;
    public:
        static UINT threadfunc(LPVOID lp);
        void set(int num1){num = num1;};
    };
    int myclass::num = 9;
    UINT myclass::threadfunc(LPVOID lp)
    {
        num ++;
    cout<<"hello world  "<<num<<endl;
    return 0;
    }
    void main()
    {
    myclass a;
    a.set(3);
    unsigned long nThreadID;
    HANDLE handle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)myclass::threadfunc,(void*)0,NULL,&nThreadID);
        WaitForSingleObject(handle,INFINITE);
    }
    如果想把CEdit 对象a传进去就在CreateThread的第4个参数为(LPVOID)&a.就可以了,在线程里面自己在给他还原回来了。
      

  10.   

    不行,如果我把那个pMain换成了this,则出错
    我把pMain去掉,也出错,就是那些变量没有生命开始的时候,我也认为是在同一个类里边就不需要再传指针了,就可以直接使用这是了,但结果却是不行的,
    真是,入门咋就这么难呢?
      

  11.   

    UINT MyThreadProc( LPVOID pParam )
    {
        CMyObject* pObject = (CMyObject*)pParam;    if (pObject == NULL ||
            !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
        return 1;   // if pObject is not valid    // do something with 'pObject'    return 0;   // thread completed successfully
    }// inside a different function in the program
    .
    .
    .
    pNewObject = new CMyObject;
    AfxBeginThread(MyThreadProc, pNewObject);
    .this is a example from MSDN.
      

  12.   

    用this不对的话,我怀疑你
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CMain::InitSQL,(void*)this,NULL,&nThreadID);
    这是不是在CMain中调用的。
    还有我还没搞懂到底谁是无效指针pMain or pConn,
    如果是在不行就把线程中要用的变量全部申明成全局的
      

  13.   

    为什么不用全局变量呢?
    如果线程A给线程B传递了一个CWnd指针而线程B要调用CWnd对象的成员函数,那么MFC在调试状态下会出现断言错误.(MFC Windows程序设计 Jeff Prosise)
    主要是因为句柄映射表对于每个线程都是本地使用的,在其他线程中不可见.如果线程A创建了CWnd,它的地址传递给了ASSERT_VALID,但是相应的HWND却不会在线程B的永久或临时的句柄映射表中出现,就会出现断言错误.
    可以通过传递真实的句柄而非对象的指针来避免断言处理发生.
      

  14.   

    谢谢各位的帮助!!现在已经可以工作了,是这样的:
    原来我在调用pConn.CreateInstance("ADODB.Connection");和pRec.CreateInstance("ADODB.Recordset");时,还没有调用那个AfxOleInit(),而是在调用CreateInstance之后才调用AfxOleInit();,所以说无效指针原来是指pConn,可我一直竟把pMain当成了无效指针,好傻,我
    另外,在OnInitDialog里已经调用过了AfxOleInit,但到了线程中还需要调用AfxOleInit