我使用TlbImp.exe
为2个COM DLL创建了一个包装器。
一个有一个包装器描述为
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 :(得分:2)
声明看起来很丑陋,我会假设它们是由某种逆向工程工具生成的,而你自己并没有写它们。在这种情况下,具有空接口并不是那么不寻常。 COM中的等价物是 dispinterface ,这是一个仅支持通过IDispatch进行后期绑定的接口。这是相当常见的,COM服务器可能设计用于脚本语言,运行时环境只支持后期绑定。与.NET中的ComInterfaceType.InterfaceIsIDispatch相同。 [DispId]对于后期绑定非常重要,可以通过数字而不是名称来调用。
这也使得论证类型易于解释。脚本语言使用VARIANT作为其变量类型。非常类似于您在C#代码中声明为 object 的变量,它可以存储任何值。功能,而不是错误。