先前发过两个帖子求助此问题,但是还有错误,麻烦各位再帮忙看一下可能是哪出的问题,在此谢过各位了。我先把代码贴出来。UINT ThreadDrawLine(LPVOID lpParam)
{
    //把参数转换成View类指针
        CoInitialize(NULL);        COpenglView* pView = (COpenglView*)lpParam;
    
        pView->DrawLine();
    
CoUninitialize();

return 0;
}void COpenglView::OnFileRead() 
{
// TODO: Add your command handler code here
//CoInitialize(NULL);
AfxBeginThread(ThreadDrawLine,this);
//CoUninitialize();
}void COpenglView::DrawLine()
{
CoInitialize(NULL); //初始化com组件;
Dxc d;
//try
{
_ConnectionPtr m_pConnection;
m_pConnection.CreateInstance(__uuidof(Connection));
m_pConnection->ConnectionString="Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=db_dixing";

m_pConnection->Open("","","",adModeUnknown);

_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance(__uuidof(Recordset));

//m_pRecordset=m_pConnection->Execute("select * from dbo.earth",NULL,adCmdText);
m_pRecordset=m_pConnection->Execute((_bstr_t)d.TP(7),NULL,adCmdText);

while(!m_pRecordset->adoEOF)
{
x=m_pRecordset->GetCollect("x");
y=m_pRecordset->GetCollect("y");
z=m_pRecordset->GetCollect("z");
r=m_pRecordset->GetCollect("r");
g=m_pRecordset->GetCollect("g");
b=m_pRecordset->GetCollect("b");

CPointzb point1;
point1.set(x,y,z);
Points1.push_back(point1);


CPointys point2;
point2.set(r,g,b);
Points2.push_back(point2;
m_pRecordset->MoveNext();
}
m_pConnection->Close();
m_pRecordset->Close();
m_pConnection->Release();
m_pRecordset->Release();
CoUninitialize();//卸载com组件
}
//  catch (_com_error& e)
//  {
//  AfxMessageBox(e.Description()+e.ErrorMessage());
//  }
}开始不知道要在线程函数里初始化COM组件,一直报无效指针的错误Unhandle Exception in ***.exe(KEDNEL32.DLL):0xE06D7363:Microsoft C++ Exception
现在在线程函数UINT ThreadDrawLine(LPVOID lpParam)里加上了这两句
CoInitialize(NULL);
CoUninitialize();
不报无效指针异常了,但是在调试的时候,在执行while(!m_pRecordset->adoEOF)
{
x=m_pRecordset->GetCollect("x");
y=m_pRecordset->GetCollect("y");
z=m_pRecordset->GetCollect("z");
r=m_pRecordset->GetCollect("r");
g=m_pRecordset->GetCollect("g");
b=m_pRecordset->GetCollect("b");

CPointzb point1;
point1.set(x,y,z);
Points1.push_back(point1);


CPointys point2;
point2.set(r,g,b);
Points2.push_back(point2);
m_pRecordset->MoveNext();
}
这个循环的时候,不定会到那一句报错这个有可能是什么原因啊,请高手指点。

解决方案 »

  1.   

     ThreadDrawLine(LPVOID lpParam) 
    我的理解,这是一个线程函数,其中调用
    DrawLine()
    你在 _ConnectionPtr m_pConnection; 没有结束生命周期,就调用了couninitlize
    所以会出错
      

  2.   

    多谢你的回答,我在ThreadDrawLine(LPVOID lpParam)里把couninitlize();注释掉,还是一样的错误。
      

  3.   

    请问我这个程序,该怎么在线程函数里对com进行初始化,高手帮帮忙啊。
      

  4.   

    CoUninitialize();//多做了一次
      

  5.   

    多谢你的回答,是线程函数UINT ThreadDrawLine(LPVOID lpParam)
    里的CoUninitialize()不需要了吗
    下面这个代码我试了一下也是不行的啊,怎么才是正确的初始化com的方法啊,请您指导一下。UINT ThreadDrawLine(LPVOID lpParam)
    {
        //把参数转换成View类指针
            CoInitialize(NULL);
           COpenglView* pView = (COpenglView*)lpParam;
           pView->DrawLine();
           //CoUninitialize();
           return 0;
    }
      

  6.   

    我跟踪了,错误是在下面这段循环中的某一句,每次执行出错的地方还不一样,但是是在这个循环里,错误就是上面那个图片的错误,不知道是咋回事while(!m_pRecordset->adoEOF)
    {
        x=m_pRecordset->GetCollect("x");
        y=m_pRecordset->GetCollect("y");
        z=m_pRecordset->GetCollect("z");
        r=m_pRecordset->GetCollect("r");
        g=m_pRecordset->GetCollect("g");
        b=m_pRecordset->GetCollect("b");
                
        CPointzb point1;
        point1.set(x,y,z);
        Points1.push_back(point1);
                
                
        CPointys point2;
        point2.set(r,g,b);
        Points2.push_back(point2);        
        m_pRecordset->MoveNext();
    }
      

  7.   

    把这几句注释掉看看
    CPointzb point1;
        point1.set(x,y,z);
        Points1.push_back(point1);
                
                
        CPointys point2;
        point2.set(r,g,b);
        Points2.push_back(point2);        
      

  8.   

    m_pConnection->Release();
    --->
    m_pConnection.Release();
      

  9.   

    把您说的那几句注释掉以后就没问题了。这个是怎么回事啊?
    CPointzb和CPointys是我建的两个类,用来存储数据库里读到的字段的值的,进而作后续处理用的,那怎么才能正确的把数据库里的数据读到对象里呢?
      

  10.   

    智能指针-> 获取的原生指针
    再对原生指针调用release();
    . 直接对 智能指针调用release();
    大致代码如此
    void Release() 
        {
            if (m_pInterface == NULL) {
                _com_issue_error(E_POINTER);
            }
            else {
                m_pInterface->Release();
                m_pInterface = NULL;
            }
        }
    而你通过->调用 已经把m_pInterface release 掉了
    m_pConnection 的脱离生命周期后 会自动调用析构函数 ,析构函数还会调用 release 出错
      

  11.   

    其实智能指针用好了不用调用release 
      

  12.   

    在外面初始化com啊,再看下是不是访问数据库出的问题,或者先把数据库访问的//掉 逐个分析是哪里出的问题
     而且我杂觉得你线程没起到什么作用啊
      

  13.   

     看看你的这个类CPointys 有没有什么问题,特别是set(r,g,b);
    这里。
      

  14.   

    呃,这个类应该不会有问题的void CPointys::set(float ir, float ig, float ib)
    {
    r1=ir/255;
    g1=ig/255;
    b1=ib/255;
    }就是把数据库里的字段值赋给对象,然后用vector<CPointys> Points2;把对象添加到容器里。
      

  15.   

    我前边已经讲了
    智能指针 -> 操作符 返回它包装的 原生指针
    class _ConnectionPtr
    {
       IUnknown _pInterface;
    .. 
    }
    m_pConnection->Release() 相当于 
    m_pConnection._pInterface->Release();
    好再看看这个智能指针的Release 如何包装.. Release()
    {
        i(_pInterface!=NULL)
        {
          _pInterface->Release();
          _pInterface=NULL;
         }
    }
    如果直接用_pInterface->Release();//因为用 ->
     这个_pInterface 并没有置NULL;
     而出了 m_pConnectionPtr 的生存期 会自动调用它的~_ConnectionPtr() 析构函数看看这个函数如何实现
     ~Connection()
     {
         Release();
      }
      

  16.   

    首先确定你是否在多个线程中执行,如果是请加锁.
    此外
    while(!m_pRecordset->adoEOF)这个好像应该用while(VARIANT_TRUE!=m_pRecordset->adoEOF)