关于DLL中调用COM的蛋疼问题

Alexander 2015-10-15 07:46:43
最近工作中遇到的头疼问题……

说明:想要把数据库的相关处理封装进一个类中
相关代码如下:


CDBService::CDBService()
{
CoInitialize(NULL);

m_pCon.CreateInstance(__uuidof(Connection));
m_pCmd.CreateInstance(__uuidof(Command));
}

CDBService::CDBService(const CDBService &ser)
{}

CDBService::~CDBService()
{
if (m_pCon->State&adStateOpen)
m_pCon->Close();

m_pCmd.Release();
m_pCon.Release();

CoUninitialize();
}

CDBService &CDBService::GetInstance()
{
static CDBService inst;

return(inst);
}

直接在工程内使用这个类是正常的,但把CDBService打包进一个DLL进行调用问题就来了:运行结束时程序会崩掉,并提示几个内存访问错误。

初步估计可能是ADO组件释放的时机有问题,还想请各位大神给个权威的说明。
...全文
142 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
牧童吃五谷 2015-10-25
  • 打赏
  • 举报
回复
你在类的析构函数中调用 CoUninitialize(...)退出了COM子系统,而你的GetInstance()中死的对象居然是static类型的,那么要在最后才释放的,所以先后顺序就不对了 建议不要做这种static 类型的变量(我编写过一个将近100万C++代码的程序,完全就不采用static)变量的
  • 打赏
  • 举报
回复
引用 5 楼 suwei2002 的回复:
[quote=引用 4楼珍惜生命远离CPP 的回复:]析构顺序问题。 增加个方法,应用退出的时候调用 ,让COM对象先释放
确实,把实例管理用指针实现就可以了,是不是说DLL资源释放之前COM服务可能已经停止了?[/quote] 静态变量析构时间在main结束之后,main结束之后 先执行哪个操作后执行哪个操作都是不确定的,也无法控制,在dll中的话可能更复杂。所以要自己控制顺序。
Saleayas 2015-10-16
  • 打赏
  • 举报
回复
如果你的主线程使用了 CoInitialize 的时候,在结束的时候,会呼叫 CoUninitialize 在关闭的时候。 假如这个线程在你使用之前已经被 Com 初始化了,很多主线程都会这样的。 那么就算你是有 CoInit ,那么你在退出的时候,你的 CoUninit 是不会关闭 Com 的。而是最初的 CoInit 函数对应的 CoUninit。 在最后的 CoUninit 才会结束 Com 的操作,比如著名的列集、散集操作和存根等等。 而此时你的 DLL 如果释放的话,那么会进入无效代码而导致内存崩溃。 如果你使用 Com 代码有代理和存根那么就不会有这个问题,系统自动处理这些问题。 或者,你不要主动使用卸载代码,而是让 Com 自动使用卸载。 如果你的主线程确保仅仅由你呼叫 CoInitialize,那么就可以解决这个问题。 你可以在你的线程中呼叫 CoInit 函数,看看返回值。
oyljerry 2015-10-16
  • 打赏
  • 举报
回复
引用 5 楼 suwei2002 的回复:
[quote=引用 4楼珍惜生命远离CPP 的回复:]析构顺序问题。 增加个方法,应用退出的时候调用 ,让COM对象先释放
确实,把实例管理用指针实现就可以了,是不是说DLL资源释放之前COM服务可能已经停止了?[/quote] 这个先后顺序应该是不能保证,所以要你显示的析构,而不是依赖析构函数
Alexander 2015-10-16
  • 打赏
  • 举报
回复
引用 4楼珍惜生命远离CPP 的回复:
析构顺序问题。 增加个方法,应用退出的时候调用 ,让COM对象先释放
确实,把实例管理用指针实现就可以了,是不是说DLL资源释放之前COM服务可能已经停止了?
  • 打赏
  • 举报
回复
析构顺序问题。 增加个方法,应用退出的时候调用 ,让COM对象先释放
oyljerry 2015-10-15
  • 打赏
  • 举报
回复
DLL中单独初始化一下com,以及设置对应的线程模型
Saleayas 2015-10-15
  • 打赏
  • 举报
回复
确保你的 DLL 在你的使用线程没有关闭之前不被卸载。
zgl7903 2015-10-15
  • 打赏
  • 举报
回复
Ole 有没有初始化? CoInitializeEx 等

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧