C#暴露给COM - 接口继承 [英] C# exposing to COM - interface inheritance

查看:183
本文介绍了C#暴露给COM - 接口继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个类BaseClass实现IBaseClass



然后我有一个接口IClass继承IBaseClass。



例如:

 

code> [ComVisible(true),InterfaceType(ComInterfaceType.IsDual),Guid(XXXXXXX)]
public interface IBaseClass
{
[PreserveSig]
string GetA ()
}

[ComVisible(true),InterfaceType(ComInterfaceType.IsDual),Guid(XXXXXXX)]
public interface IClass:IBaseClass
{
[PreserveSig]
string GetB()
}

[ComVisible(true),ClassInterface(ClassInterfaceType.None),Guid(XXXXXXX)]
public class BaseClass:IBaseClass
{
public string GetA(){returnA; }
}

[ComVisible(true),ClassInterface(ClassInterfaceType.None),Guid(XXXXXXX)]
public class Class:BaseClass,IClass
{
public string GetB(){returnB; }
}

当暴露给COM时,如果我创建一个Class不允许我调用GetA()。



在.tlb文件中查看我的IDL时,我的IClass界面如下:

  [
odl,
uuid(XXXXXXXXXXXXXXXXXXX),
version(1.0),
dual,


$ b接口IClass:IDispatch {
[id(0x60020000)]
BSTR GetB();
}

它甚至看起来不像IClass派生自IBaseClass!



如果我取出IClass从IBaseClass派生,只是添加方法到界面,它的工作原理。



使C#在COM中启用此继承?我不想重新实现接口,当我可以继承他们。



CRAP:检查此链接 Net COM Limitation



如果有人回答为什么这是,或更好的解决方法,复制粘贴到我的派生接口,让我知道。

解决方案

这不是一个.NET问题,它是一个COM工作方式的后果。它不支持继承。你可以在客户端解决这个问题,它需要调用QueryInterface()与IID为IBaseClass获得一个接口指针到IBaseClass接口,所以它可以调用GetA()。 .NET互操作自动提供一个QI实现,使这项工作。但是,在这种情况下,它不是非常用户友好,设计您的C#端代码,使客户端使用您的类,而不是相反的方式。你通常需要一个单线程覆盖方法来委托给基本的C#类实现。



注意,你的方法签名有问题,使用[ PreserveSig]属性。它们不能通过IDispatch调用,也不能自动编组。这需要一个具有HRESULT作为返回值类型的方法。当您移除属性时,这是自动的。


Say I have a class BaseClass that implements IBaseClass

Then I have an interface IClass that inherits IBaseClass.

Then I have a class named class that implements IClass.

For example:

[ComVisible(true), InterfaceType(ComInterfaceType.IsDual), Guid("XXXXXXX")]
public interface IBaseClass
{
  [PreserveSig]
  string GetA()
}

[ComVisible(true), InterfaceType(ComInterfaceType.IsDual), Guid("XXXXXXX")]  
public interface IClass : IBaseClass
{
  [PreserveSig]
  string GetB()
}

[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("XXXXXXX")]
public class BaseClass : IBaseClass
{
  public string GetA() { return "A"; }
}

[ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("XXXXXXX")]
public class Class : BaseClass, IClass
{
  public string GetB() { return "B"; }
}

When exposing to COM, if I make an instance of "Class" it does not allow me to call GetA().

When looking my IDL in the .tlb file, my IClass interface looks like:

[
  odl,
  uuid(XXXXXXXXXXXXXXXXXXXXX),
  version(1.0),
  dual,
  oleautomation,

]
interface IClass : IDispatch {
    [id(0x60020000)]
    BSTR GetB();
}

It doesn't even look like IClass derives from IBaseClass!

If I take out where IClass derives from IBaseClass and just add the methods to the interface, it works.

How can I make C# enable this inheritance in COM? I'd rather not re-implement interfaces when I can inherit them.

CRAP: check this link .Net COM Limitation

If someone has an answer to why this is, or a better workaround than copy-paste to my "derived" interface, let me know. If not, I'll mark an answer in a couple days.

解决方案

This is not a .NET problem, it is a consequence of the way COM works. It doesn't support inheritance. You would fix this at the client side, it needs to call QueryInterface() with the IID for IBaseClass to get an interface pointer to the IBaseClass interface so it can call GetA(). .NET interop automatically provides a QI implementation that makes this work. However, it is not very user-friendly in this case, design your C# side code to make it easy for the client to use your class instead of the other way around. You'd typically need a one-liner override method that delegates to the base C# class implementation.

Note that there's a problem with your method signatures and the use of the [PreserveSig] attribute. They are not callable through IDispatch nor can they be auto-marshaled. That requires a method with a HRESULT as the return value type. It is automatic when you remove the attribute.

这篇关于C#暴露给COM - 接口继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆