void __stdcall test()
{
  ::CoInitialize(NULL);
  _ConnectionPtr pconn;
  pconn.CreateInstanse( __uuidof(Connection));
  pconn.Open(...);
  pConn.Close();
  pConn.Release();
  ::CoUninitialize();
}上面这个函数是动态库里面的一个接口函数,省略了一些try语句,open中的参数是对的,也就是能够open成功。该函数被同一线程调用多次后,为什么会出问题啊?
一般第一次好像没什么问题,后面的调用就会报一个“读取位置 0x4a1b6b45 时发生访问冲突”之类的错误。
初步验证了函数中要是去掉
  pconn.Open(...);
  pConn.Close();
这两句的话,调用是没有问题的。

解决方案 »

  1.   

    你的 pconn 如果不是在线程函数内部申请的,或者是全局的pconn ,那就肯定会出问题因为 一个线程初始化com库 打开连接都是需要时间的,这个线程的工作还没完成,你其他的线程就执行关闭或其它 pconn的操作当然会出错的!
      

  2.   

    如果只有一个线程调用该函数,那么对Test()的调用是串行的;如果有多个线程调用该函数,不存在共用变量访问冲突呀
      

  3.   

    这个问题似乎有了点眉目。
    今天灵感来了^^
    考虑到每次挂掉的时候,没有运行任何用户代码,故我认为_ConnectionPtr的Close()与Release()是异步函数
    在Close()或Release()没有充分执行完成就调用::CoUninitialize(),将会产生上述的错误。
    于是我在::CoUninitialize()前加上一条Sleep(500),问题不出现了!!!问题是否已经解决了,等我在虚拟机上试了再作定论吧...
      

  4.   

    虚拟机上问题也不再出现。
    暂且这样认为:调用Close()与Release()释放连接是需要时间的,这在性能不好的机器上(包括虚拟机)就表现为连接资源还在释放过程当中(我认为是异步释放),但线程已经开始调用CoUninitialize()了,这势必产生问题;故在性能好的机器上基本上没有问题的现象就可以解释了。解决办法就是在CoUninitialize()调用之前让线程切换去继续释放连接资源,Sleep()一下是不错的选择。谢谢saylerboxer 和marrco2005的关注