Как передать один экземпляр класса COM в качестве параметра другому методу COM в C #? - PullRequest
2 голосов
/ 02 февраля 2012

Я создал оболочку для 2-х библиотек COM, используя TlbImp.exe.У одного есть класс, который оболочка описывает как

using System;
using System.Runtime.InteropServices;

namespace GNOTDRSIGNATURESERVERLib
{
    [CoClass(typeof(GNOTDRSignatureServerClass)),
        Guid("20CBF9E0-06BF-11D3-97B5-0080C878CFFA")]
    public interface GNOTDRSignatureServer
    {
    }
}

Этот объект должен быть передан как параметр

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace GN8000Lib
{
    [TypeLibType(2),
         ClassInterface(0), 
         ComSourceInterfaces("GN8000Lib._I8000Events\0"),
         Guid("DCAD84FE-43A8-11D3-B1A2-005004131886")]
    public class GN8000Class : I8000
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        public extern GN8000Class();

        [DispId(6)]
        [MethodImpl(MethodImplOptions.InternalCall)]
        void I8000.Initialize(
            [IUnknownConstant] [MarshalAs(UnmanagedType.IUnknown)] [In]
            object pSigServer = null);
    }
}

Затем я вызываю метод следующим образом:

var gn8000 = new GN8000();
var signatureServer = new GNOTDRSignatureServer();
gn8000.Initialize(signatureServer);

Я думаю, что передаваемый объект не является правильным.Я чувствую, что TlbImp.exe может связать эти библиотеки DLL и использовать GNOTDRSignatureServer вместо UnmanagedType.IUnknown или что я могу использовать System.Runtime.InteropServices.Marshal.GetComInterfaceForObject

Что не так с моим кодом?

1 Ответ

2 голосов
/ 02 февраля 2012

Объявления выглядят довольно некрасиво, я предполагаю, что они были сгенерированы каким-то инструментом реинжиниринга, а вы сами их не написали. В этом случае наличие пустого интерфейса не так уж и необычно. Эквивалентом в COM является dispinterface , интерфейс, который поддерживает только позднюю привязку через IDispatch. Это довольно часто, COM-сервер, возможно, был разработан для работы с языками сценариев, средами выполнения, которые поддерживают только позднюю привязку. То же самое, что ComInterfaceType.InterfaceIsIDispatch в .NET. [DispId] важен для поздней привязки, звоните по номеру вместо имени.

Что также облегчает объяснение типа аргумента. Языки сценариев используют VARIANT в качестве своего типа переменной. Очень похоже на переменную, которую вы объявите как object в коде C #, она может хранить любое значение. Функция, а не ошибка.

...