这只是关于如何为COM导入编写代码的问题。

我对互操作接口正确实现的理解是,主要标准是:

  1. 所有方法签名必须以兼容的方式匹配
  2. 方法必须在.Net界面中以与在非托管界面中完全相同的顺序出现
  3. 当非托管接口继承自另一个非托管接口时,托管实现必须首先声明基本级别的接口成员,从最基本的接口开始。
  4. 我的问题是;关于成员出现的顺序,如果我导入的接口是从另一个接口继承并覆盖/隐藏基接口中的一个或多个成员,我该怎么办?接口成员声明在哪里?首先,基地接口声明了什么?或者从原始位置移除并放置在派生接口声明它的位置?

    [uuid(31d1c294-1dd2-11b2-be3a-c79230dca297)]
    interface BaseComInterface
    {
        void method1();
        void method2();
        void method3();
    }
    
    [uuid(fab51c92-95c3-4468-b317-7de4d7588254)]
    interface DerivedComInterface : BaseComInterface
    {
        void method1();
        void method4();
        void method5();
    }
    

    现在为C#代码:

    [Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IDerivedComInterface
    {
        void method1(); // do I remove this one?
        void method2();
        void method3();
        void method1(); // or this one?
        void method4();
        void method5();
    }
    
有帮助吗?

解决方案

你有一个实际上这样做的例子吗?虽然COM在接口和从其派生的另一个接口中具有相同的名称是完全合法的,但它使得在几乎所有开发环境中难以或不可能使用派生接口。这包括实现以及基于接口调用任何COM对象。

在COM接口中没有覆盖或隐藏的东西。 COM接口只是一个如何将对象的二进制接口布局在内存中的契约,除了工具之外,接口定义中的方法名称是没有意义的。在你的情况下,BaseComInterface承诺一个'vtable'有六个方法,前三个匹配IUnknown方法的签名,接下来三个匹配你给出的三个方法的签名,所有方法都正确。另一方面,DerivedComInterface承诺包含9个方法的'vtable',前三个签名再次与IUnknown方法匹配,接下来的三个匹配BaseComInterface方法的签名,后三个匹配DerivedComInterface特有的三个方法。这些方法的名称是无关紧要的,除了你的IDE,工具和编译器需要名字来找到'vtable'指针。

基本上,在C#以及C,C ++和其他一些语言中,为了实现DerivedComInterface,需要对其中一个方法名称进行修饰,以区分它的“vtable”插槽。

要回答你的问题 - 你不会删除任何方法,因为他们都需要在那里履行COM合同:

[Guid("fab51c92-95c3-4468-b317-7de4d7588254"), ComImport,  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDerivedComInterface
{
    void method1(); 
    void method2();
    void method3();
    void method1_2(); //Decorated to distinguish from base interface method.
    void method4();
    void method5();
}

这忽略了如果这些接口派生自IDispatch而不是IUnknown会发生什么,这是我不想进入的混乱。另外,请记住,如果您的idl确实将方法定义为返回void,则必须使用PreserveSig属性修饰C#方法。

其他提示

我建议你使用显式接口成员实现避免冲突。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top