当一个函数(来自一个库)包含在 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。
按 Tab 启用图像级别选项。
在调试器选项中输入 windbg 的完整路径 -g
这将导致您的 exe 每次启动 xyz.exe 时都会附加调试器。
现在要在 CoInitialize 调用上设置断点,在 Windbg 中中断执行。 在命令窗格中输入
bp Ole32!CoInitialize
停止调试,提示时保存工作区并重启xyz.exe
这一次,当任何人调用 CoInitialize 时,应用程序将进入调试器。
希望对你有帮助
【讨论】:
【参考方案5】:一个常见的错误是如果引用的 DLL 丢失,所以当 CoInitialize 被调用时,它会尝试加载 DLL 并以旧的 E_FAIL 失败。尝试使用依赖遍历器并检查您可能错过的任何 DLL。
【讨论】:
以上是关于当一个函数(来自一个库)包含在 VC++ MFC 项目中时,“CoInitialize failed”的主要内容,如果未能解决你的问题,请参考以下文章
正常的 Windows 安装是不是包含 MFC100.dll?