我的C#应用程序在运行时调用C ++ DLL中的函数并引发异常。生成的错误代码是262.不幸的是,Microsoft documentation对此代码有点缺乏。
奇怪的是,从C ++测试应用程序运行DLL时不会引发此异常,该应用程序是与DLL(单独项目)相同的Visual Studio解决方案的一部分。 (C#应用程序是完全独立的解决方案。)错误代码通过调用CoInitializeEx
返回,它初始化COM,是我的应用程序用来查询WMI的第一步。
唯一似乎是相关的另一件事是当我用Dependency Walker打开DLL时,我收到了这些错误和警告:
错误:找不到至少一个必需的隐式或转发依赖项 警告:找不到至少一个延迟加载依赖模块 警告:由于延迟加载相关模块中缺少导出功能,至少有一个模块具有未解析的导入。
我遇到的唯一问题是缺少“必需的隐式或转发依赖”,使得CoInitializeEx
有效。根据Dependency Walker的说法,找不到这些模块:
任何想法或建议都表示赞赏。感谢。
答案 0 :(得分:4)
您的错误处理不是Kosher,您可能得到的真正错误是0x80010106,最后一个字是262.错误代码是RPC_E_CHANGED_MODE,“设置后无法更改线程模式”。 CoInitialize / Ex在之前调用时返回的是您尝试从STA更改为MTA或其他方式。
这是不可能的,线程的公寓状态在第一次调用CoInitializeEx()时被锁定。你需要找出第一次电话的发生地点。例如,这可以由CLR为托管线程完成。线程的单元状态由启动线程的Main()方法上的[STAThread]或[MTAThread]确定。或者您自己创建的托管线程的Thread.SetApartmentState()。线程池线程始终是MTA,无法更改。
更改线程的公寓状态可能会产生许多副作用。
答案 1 :(得分:1)
我假设你没有安装Visual Studio 2008 C ++,因为你有MSVCR90D.dll这个dll只是一个调试dll,这意味着你正在尝试加载一个已编译为调试DLL的DLL。
至于其他人......请参阅此主题:Dependency Walker reports IESHIMS.DLL and WER.DLL missing?
答案 2 :(得分:1)
在您的特定场景中,单独的线程可能是您最好的选择。
从DLL创建线程是一件混乱的事情,因为DLL并不拥有该进程的生命周期;所有者是EXE。
但是...... 如果你以同步的方式运行它(创建线程;初始化;等待线程完成;然后继续),你通常是安全的。你可以缓存线程,所以你不必每次都创建和CoInitialize()它,但不要让它在后台运行并返回给你的调用者:再次,出现微妙的生命周期问题。
答案 3 :(得分:0)
检查您是否已在发布或调试模式下编译了所有内容。
您是否使用了I.E的任何基于http的功能?我很好奇为什么你依赖ieshims.dll。
答案 4 :(得分:0)
错误WIN32 = 262是HRESULT = -2147024634(0x80070106)。这是别的。
应该只为每个线程调用CoInitializeEx
一次,但如果多次调用它,则CoUninitialize
应该有一个CoInitializeEx
。