2012-02-02 4 views
1

Я создал обертку для 2 COM-библиотек, используя TlbImp.exe. Один имеет класс, обертка описывает какКак передать один экземпляр COM-класса в качестве параметра другому методу COM в C#?

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

Что случилось с моим кодом?

+0

Какая ошибка вы получаете? Кроме того, я не вижу никаких описаний методов интерфейса. Вы уверены, что это правильная подпись? – casperOne

+0

@casperOne Ошибка, которую я получаю, заключается в том, что объекты должны взаимодействовать, как в примере кода VBScript, который я использую в качестве руководства, и они не находятся на C#. Я удалил некоторые методы из интерфейса перед публикацией, потому что они не имеют отношения к этому вопросу. –

ответ

2

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

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

+0

Да, код, указанный выше, был создан 'TlbImp.exe'. Я удалил некоторые методы из интерфейса перед публикацией, потому что они не имеют отношения к этому вопросу. –