2012-02-02 33 views
1

我使用TlbImp.exe为2个COM DLL创建了一个包装。 一个具有包装描述为如何将一个COM类实例作为参数传递给C#中的另一个COM方法?

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 2012-02-02 13:41:41

+0

@casperOne我得到的错误是对象必须交互,就像他们在我用作指导的示例VBScript代码中所做的那样,它们不在C#中。我在发布之前从界面中删除了一些方法,因为它们与此问题无关。 – 2012-02-02 14:59:47

回答

2

声明看起来非常难看,我会假设它们是由某种逆向工程工具生成的,而你自己并没有写出它们。在这种情况下,有一个空的界面并不是那么不寻常。 COM中的等价物是调度接口,该接口仅支持通过IDispatch进行后期绑定。这很常见,COM服务器可能被设计为与脚本语言,仅支持后期绑定的运行时环境一起工作。与.NET中的ComInterfaceType.InterfaceIsIDispatch相同。 [DispId]对于后期绑定非常重要,通过号码而不是名称来呼叫。

然后这也使得参数类型容易解释。脚本语言使用VARIANT作为它们的变量类型。非常类似于你在C#代码中声明为对象的变量,它可以存储任何值。功能,而不是一个错误。

+0

是的,上面的代码是由'TlbImp.exe'生成的。我在发布之前从界面中删除了一些方法,因为它们与此问题无关。 – 2012-02-02 15:01:04

相关问题