C# 对COM互操作的肤浅理解导致类型_E_CANTLOADLIBRARY exception-where';错在哪里?
我们有一个.Net程序集a,它使用COM库B中的类C# 对COM互操作的肤浅理解导致类型_E_CANTLOADLIBRARY exception-where';错在哪里?,c#,.net,com,com-interop,C#,.net,Com,Com Interop,我们有一个.Net程序集a,它使用COM库B中的类Foo 我们已经为B创建了一个互操作(interop.B.dll),A通过互操作使用Foo 如果我反编译Interop.b.dll,我可以看到其中定义的以下接口: using System.Runtime.InteropServices; namespace Interop.b { [Guid("SOME-GUID")] [CoClass(typeof (FooClass))] [ComImport] public interf
Foo
我们已经为B创建了一个互操作(interop.B.dll
),A通过互操作使用Foo
如果我反编译Interop.b.dll
,我可以看到其中定义的以下接口:
using System.Runtime.InteropServices;
namespace Interop.b
{
[Guid("SOME-GUID")]
[CoClass(typeof (FooClass))]
[ComImport]
public interface Foo : _Foo
{
}
}
在.Net程序集A的引用设置中,我可以选择嵌入interop.b.dll
的互操作类型。如果我将其设置为true
,则Interop.b.dll
中定义的接口将嵌入A.dll
中。如果我随后反编译A.dll
,我可以看到与interop中相同的界面:
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Interop.b
{
[CompilerGenerated]
[Guid("SOME-GUID")]
[CoClass(typeof (object))]
[TypeIdentifier]
[ComImport]
public interface Foo : _Foo
{
}
}
除了不一样。在这个版本中,我们将[TypeIdentifier]
作为附加属性,并且CoClass
属性的参数已从typeof(FooClass)
更改为typeof(object)
我注意到Interop.b.dll
包含类型FooClass
,我认为它是COM类型Foo
的包装类,负责在.Net和COM之间编组参数类型,但该类型尚未嵌入a.dll
在A.dll
中,Foo
的使用方式如下:
using Interop.b;
namespace My.Product
{
public class AClass: IAClass
{
private Foo LocalFoo { get; }
public AClass()
{
LocalFoo = new Foo();
}
}
}
在干净的安装中,此操作失败,出现以下异常:
System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'Interop.b.Foo'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{SOME-GUID}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).
(Interop.b.dll
已由产品安装程序安装到GAC)
在开发机器上,重新安装产品并从已安装的二进制文件运行也会以同样的方式失败。随后重新编译产品,覆盖已安装的二进制文件,然后从代码(调试中)或新二进制文件运行
现在,我认为错误在于A.dll
中的代码应该实例化FooClass
,而不是Foo
。i、 例如:
LocalFoo = new FooClass();
…因为Foo
是一个接口(在互操作中),而FooClass
是处理.Net和COM之间的参数类型编组的东西
因此,问题是:
1) 代码应该实例化FooClass
,而不是Foo
,对吗
2) 为什么它在开发机器上工作
3) 为什么嵌入式接口使用typeof(object)
而不是typeof(FooClass)
4) 当我们仍然需要在目标机器上使用
interop.b.dll
时,将interop中的接口嵌入A.dll
有什么好处,以允许我们使用FooClass
?interop程序集或嵌入式interop程序集只是向.NET解释coclass是什么的元数据定义,基本上,接口、guid以及接口方法是如何为COM组件进行布局的。如果已嵌入类型,则不需要interop.dll。此外,如果您的A组件需要类型库,则必须安装它,.NET或不安装。对我来说,似乎你的安装程序必须是固定的。它可以在你的开发机器上运行,因为你的COM组件已经在上面正确注册了,问同样的问题:这里的附加信息:你找错了树。这些链接包含问题1和4的答案。互操作程序集或嵌入式互操作程序集只是元数据定义,它们向.NET解释了COM组件的类、接口、GUID以及接口方法的布局,基本上。如果已嵌入类型,则不需要interop.dll。此外,如果您的A组件需要类型库,则必须安装它,.NET或不安装。对我来说,似乎你的安装程序必须是固定的。它可以在你的开发机器上运行,因为你的COM组件已经在上面正确注册。注意:9年前的这个问题实际上是在问同一个问题:这里的附加信息:你在错误的树上吠叫。这些链接包含问题1和问题4的答案。