这只是关于如何为COM导入编写代码的问题。
我对互操作接口正确实现的理解是,主要标准是:
我的问题是;关于成员出现的顺序,如果我导入的接口是从另一个接口继承并覆盖/隐藏基接口中的一个或多个成员,我该怎么办?接口成员声明在哪里?首先,基地接口声明了什么?或者从原始位置移除并放置在派生接口声明它的位置?
[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();
}
答案 0 :(得分:1)
你有一个实际上这样做的例子吗?虽然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#方法。
答案 1 :(得分:0)
我建议您使用explicit interface member implementations来避免冲突。