Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对COM互操作的肤浅理解导致类型_E_CANTLOADLIBRARY exception-where';错在哪里?_C#_.net_Com_Com Interop - Fatal编程技术网

C# 对COM互操作的肤浅理解导致类型_E_CANTLOADLIBRARY exception-where';错在哪里?

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

我们有一个.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 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的答案。