![](/img/trans.png)
[英]C++ Windows Shell Extensions - Win7 32bit - 64bit compatibility issues
[英]Simple C++ .Net console app crashing in 64 bit Win7
我公司使用第3方DLL来连接某些硬件(在这里我将其重命名为hwLib
)。 我想这是很久以前用VB6编写的。 DLL带有安装程序以进行自身注册,等等。
我们有一个使用它的C#应用,它可以在XP和Win7(32或64位)上正常运行。 但是我写了一个简单的C ++控制台应用程序,它可以在XP / 32位上正常运行,但在Win7 / 64位上崩溃。
#include "stdafx.h"
using namespace System;
int main(array<System::String ^> ^args)
{
using namespace hwLib;
ChwLib^ myLib = gcnew ChwLib();
String^ str = myLib->GetDllVersion();
Console::WriteLine(L"Hello hwLib");
Console::WriteLine(str);
Console::ReadLine(); //to keep window open til you hit the "any" key
return 0;
}
未处理的异常:System.InvalidCastException:无法将类型为“ hwLib.ChwLibClass”的COM对象强制转换为接口“ hwLib._ChwLib”。
该操作失败是因为对IID为“ {E0560D1E-9A54-4EBF-83E8-D7BD2C936512}”的接口的COM组件上的QueryInterface调用由于以下错误而失败:
不支持这样的接口(HRE SULT的异常:0x80004002(E_NOINTERFACE))。 在System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc,IntPtr pCPCMD,Boolean&pfNeedsRelease)在hwLib.ChwLibClass.GetDllVersion()在main(String [] args)在mainCRTStartupStrArray(String []参数)
C#程序是一个更大,更复杂的程序,否则我会在这里发布它,它在同一系统上运行没有问题。
COM早于我的著作-我可能在10或15年前就参加了课程,但我不记得了-关于如何开始调试它的任何建议? 谢谢!!
COM为声明自己不支持线程的COM组件提供线程安全保证。 用VB6编写的任何组件都可以做到这一点。 由注册表中名为ThreadingModel的条目指示。
您的测试程序无法为此类组件提供安全的家,您的控制台模式应用会创建一个多线程单元,简称MTA。 这保证不会提供线程安全性。 然后,COM创建自己的STA线程来运行该组件的代码。 对组件的每次调用都将从主线程编组到该辅助线程。
但是,如果遇到这种情况,它就会碰壁,您的组件没有注册所需的代理/存根。 COM需要弄清楚如何复制该方法的参数的额外代码。 在.NET中很容易,这要归功于Reflection,而不是COM。 代理/存根由HKCR \\ Interface注册表项中的条目选择,VB6组件始终使用与类型库一起使用的标准编组器。 E_NOINTERFACE错误代码用于IMarshal接口,这是COM的最后一次尝试,而不是由VB6实现。
除了获得正确的注册之外,临时帮助使控制台模式应用程序可以创建STA线程而不是MTA线程。 这很容易做到,只需要一个属性:
[STAThread]
int main(array<System::String ^> ^args)
// etc..
现在,COM不再创建该帮助程序线程,也不必整理呼叫。 实际上这还不够,STA线程还必须泵送消息循环。 Application :: Run()可能在较大的C#程序中使用。 消息循环提供了封送呼叫的方式,与Control.BeginInvoke()和Dispatcher.BeginInvoke()非常相似。 因为您实际上并没有从另一个线程对该组件进行调用,所以您可能会放弃它。 但是许多COM组件依靠消息循环来完成自己的工作。 当您看到死锁或组件未引发事件时,您就会知道有问题。 例如,VB6代码可以使用计时器,没有该消息循环就不会打勾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.