当一个函数(来自一个库)包含在 VC++ MFC 项目中时,“CoInitialize failed”

Posted

技术标签:

【中文标题】当一个函数(来自一个库)包含在 VC++ MFC 项目中时,“CoInitialize failed”【英文标题】:"CoInitialize failed" when one function (from a lib) is included in VC++ MFC project 【发布时间】:2009-04-14 15:32:53 【问题描述】:

我知道这有点含糊,我只是在这里寻找一般可能性,以使我走上正轨。

我在我的 MFC Dialog 程序中包含两个库和它们的 .h 并编译它,没问题。但是,当我从其中一个库调用函数时,它会弹出一个对话框,显示“Com Error”“CoInitialize Failed”。那不是我真正调用函数的时候,而是程序开始运行的时候。我的假设是,当它看到函数时,它实际上调用了 lib,当它调用时,可能在我的 MFC 程序中调用 CoInit 之前调用了 CoInit,从而造成冲突?

单步执行代码,它似乎在 CDialog::DoModal 处抛出了这个

我总是可以添加更多细节,我只是希望能够朝着正确的方向前进。非常感谢您的帮助!

编辑:

问题是,我不知道 DLL 在哪里调用 CoInitialize。我真的不能发布代码,因为代码太多了,即使是一个简单的程序也是如此。我会尝试依赖 walker 并查看我的 InitInstance... 还有其他建议吗?非常感谢大家

【问题讨论】:

用实际的源代码调试这样的问题总是最容易的,尤其是你可以创建的最小的例子来展示问题。 “最容易调试”适用于没有看到源代码而是依赖您的描述的人。 【参考方案1】:

尝试添加您自己对 CoInitializeEx 的调用,并确保您在主线程中使用 STA (SingleThreadedApartment) 线程。

很有可能正在将您的主线程设置为 MTA,但您的库需要 STA,因此 CoInitialize 调用失败。

【讨论】:

【参考方案2】:

一个好的方向是添加更多细节,特别是如果你有它们,比如 CoInitialize 返回的 HRESULT 是什么?

我的猜测是这样的库有一个静态初始化,如果没有调用来自 dll 的函数,它们会被链接器丢弃,但如果至少调用了一个函数,那么静态初始化器就会被链接。

【讨论】:

【参考方案3】:

您应该在您的 App InitInstance() 中调用 CoInitialize。然后它应该在调用 DoModal() 之前执行。

可能此错误消息并不表示该库尝试调用 CoInitialize 本身,而是尝试了其他一些 COM 调用,并且从那里收到的错误推断出您没有调用 CoInitialize。

【讨论】:

【参考方案4】:

您可以通过在其上设置断点来找出谁在调用 CoInitialize。

这就是您使用Debugging Tools for Windows 的方式。

您首先使用 gflags.exe 为您的 exe 启用调试器选项。

为此

    运行 gflags.exe 在图像文件选项中给出你的 exe 的名称,比如 xyz.exe。 按 T​​ab 启用图像级别选项。 在调试器选项中输入 windbg 的完整路径 -g

这将导致您的 exe 每次启动 xyz.exe 时都会附加调试器。

现在要在 CoInitialize 调用上设置断点,在 Windbg 中中断执行。 在命令窗格中输入

bp Ole32!CoInitialize

停止调试,提示时保存工作区并重启xyz.exe

这一次,当任何人调用 CoInitialize 时,应用程序将进入调试器。

希望对你有帮助

【讨论】:

【参考方案5】:

一个常见的错误是如果引用的 DLL 丢失,所以当 CoInitialize 被调用时,它会尝试加载 DLL 并以旧的 E_FAIL 失败。尝试使用依赖遍历器并检查您可能错过的任何 DLL。

【讨论】:

以上是关于当一个函数(来自一个库)包含在 VC++ MFC 项目中时,“CoInitialize failed”的主要内容,如果未能解决你的问题,请参考以下文章

基于VC++的MFC类库实现的简单FTP客户端

VC学习笔记---ATL MFC CLR三个库的区别

正常的 Windows 安装是不是包含 MFC100.dll?

VC/MFC动态库Debug版本下正常,Release版本下错误

VC定义的三种类型DLL有啥区别

MFC调用C动态库函数-----待补充