C++调用C#COM互操作错误:HRESULT 0x80131509
本文关键字:HRESULT 0x80131509 错误 互操作 调用 C#COM C++ | 更新日期: 2023-09-27 18:22:18
我为C++创建了一个要调用的C#COM互操作。我已经通过regasm注册了dll和tlb文件。一切都很顺利,直到有一天我更改了C#部分的代码(我没有更改接口的定义,只是更改了实现)。COM中的一个接口返回错误0x80131509。奇怪的是,它只发生在一些电脑上(我开发的电脑运行良好,所以我无法调试这个问题)。我真的不清楚C#COM是如何使用C++的,在我注册了它们之后,我只知道它们在窗口注册表中创建键值。(就像regasm/regfile生成的一样)。c++如何知道COM dll(搜索路径环境变量)在哪里?tlb文件在运行时有什么用?
有什么建议吗?
我在COM库中引入了一个简单的继承层次结构后,就出现了同样的错误。快速解决方案是在基类上将ComVisible属性设置为true。这立刻解决了我的问题。
仔细想想,这确实很有意义——编译器不允许您在基类不如继承类可见的情况下构建层次结构。因此,COM也是如此,这并不奇怪——唯一的区别是,它在运行时而不是编译时失败。
我敢说,错误的真正原因是构造函数链断裂,但我没有对此进行进一步研究。
我认为您的问题与注册表有关。。。您应该尝试在出现此问题的计算机中注销并注册(使用regasm)您的dll。
如果这不起作用,请在这些计算机中注销dll,然后使用regedit搜索并删除任何缺少的引用它的注册表项,然后再次注册dll。你也可以在删除丢失的注册表项后使用其中一个注册表清理程序来保证你不会错过任何东西。
请记住,您应该始终在应用程序将要使用的目录中注册dll,并且这种情况应该只发生一次。如果您需要注销dll,那么您应该始终在用于注册的同一目录中进行。换句话说,一旦注册了dll,就不要移动它。
注意:如果您的dll与C++应用程序不在同一路径上,则它应该位于path环境变量中引用的目录中。
当我从Visual FoxPro调用.Net4 C#COM对象时,收到了相同的错误消息。
该方法返回对象,该对象的类型可以是多个对象中的一个。所有类型都是从一个抽象类派生而来的,该抽象类实现了一个具有这些类型的公共内容的接口。
最终,我决定从基类中删除抽象修饰符,并将其公开和ComVisible。这为我解决了问题,尽管我希望基类是抽象的。