在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中不存在。
如果更改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接口。