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

本文关键字:COM 对象 | 更新日期: 2023-09-27 18:26:42

我想在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() {
    }
  }
}

我在将DLL添加到全局程序集缓存时使用了gautil。

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();
}

当执行行object o=new TestObject()时,我得到一个InvalidCastException。这个代码出了什么问题?

Test.exe中发生"System.InvalidCastException"类型的未处理异常附加信息:Das Objekt des Typs"TestComServer.TestObject"在Typ"TestObject"umgewandelt werden中不存在。

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

如果更改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接口。