在C#中编写COM对象并在C#中使用它

时间:2012-03-05 22:56:13

标签: c# com .net

我想在C#中实现一个COM对象,并在C#中使用它(除了C ++和其他)。

以下是实现COM对象的DLL的代码:

namespace TestComServer {
  [ComVisible(true),
  Guid("565D8202-6C0F-4AAB-B0F6-49719CD13045"),
  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
  ]
  public interface ITestObject {
    void DoSomething();
  }

  [
  ComVisible(true),
  GuidAttribute("21293767-A713-49E2-968E-7DDE0B0DAB94"),
  ClassInterface(ClassInterfaceType.None)
  ]
  public class TestObject : ITestObject {
    public TestObject() {
    }

    public void DoSomething() {
    }
  }
}

我已经使用gacutil将DLL添加到全局程序集缓存中。

EXE以下列方式使用COM对象(就像我成功地使用C ++实现的一些COM对象一样):

[
ComImport(),
Guid("565D8202-6C0F-4AAB-B0F6-49719CD13045"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface ITestObject {
  [PreserveSig ]
  void DoSomething();
}

[ComImport, Guid("21293767-A713-49E2-968E-7DDE0B0DAB94")]
public class TestObject {
}

private void button1_Click(object sender, EventArgs e) {
  object o = new TestObject();
  ITestObject t = (ITestObject)o;
  t.DoSomething();
}

执行行对象o = new TestObject(); 时,我收到InvalidCastException。这段代码有什么问题?

  

Test.exe中发生了未处理的“System.InvalidCastException”类型异常   附加信息:Das Objekt des Typs“TestComServer.TestObject”kann nicht in Typ“TestObject”umgewandelt werden。

1 个答案:

答案 0 :(得分:0)

如果更改EXE以便它只导入接口,则使用Type.GetTypeFromCLSID和Activator.CreateInstance实例化对象:

[
ComImport(),
Guid("565D8202-6C0F-4AAB-B0F6-49719CD13045"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface ITestObject {
  [PreserveSig ]
  void DoSomething();
}

private void button1_Click(object sender, EventArgs e) {
  Type type = Type.GetTypeFromCLSID(new Guid("21293767-A713-49E2-968E-7DDE0B0DAB94"));
  object o = Activator.CreateInstance(type);
  ITestObject t = (ITestObject)o;
  t.DoSomething();
}

之前我没有使用过导入COM对象的方法,所以这可能不起作用。通常我在一个单独的程序集中定义我的接口,该程序集也暴露给COM,然后由DLL和EXE引用。 EXE使用上述方法实例化DLL并将其强制转换为它引用的.NET接口。