У нас есть сборка. Net, A, которая использует класс Foo
из библиотеки COM, B.
Мы создали взаимодействие для 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
, я вижу тот же интерфейс, который я нашел во взаимодействии:
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
установлено на GA C от установщика продукта)
На компьютере разработчика переустановка продукта и запуск из установленных двоичных файлов не выполняется аналогичным образом. После этого перекомпилируется продукт, который перезаписывает установленные двоичные файлы и работает либо из кода (в отладке), либо из двоичных файлов fre sh.
Теперь я считаю, что ошибка заключается в том, что код в A.dll
должен быть экземпляр FooClass
, а не Foo
. то есть что-то вроде этого:
LocalFoo = new FooClass();
... потому что Foo
- это интерфейс (во взаимодействии), а FooClass
- это то, что обрабатывает сортировку типов параметров между. Net и COM.
Итак, вопросы:
1) Правильно ли я считаю, что код должен быть экземпляром FooClass
, а не Foo
?
2) Почему он работает вообще на компьютере разработчика?
3) Почему во встроенном интерфейсе используется typeof(object)
вместо typeof(FooClass)
?
4) В чем преимущество внедрения интерфейсов из взаимодействия в A.dll
когда нам все еще понадобится Interop.b.dll
на целевой машине, чтобы мы могли использовать FooClass
?