2009-10-24 3 views
1

이것은 COM 가져 오기를위한 코드 작성 방법에 대한 질문입니다.interop 인터페이스를 올바르게 선언하는 방법에 대한 설명

  1. 모든 메소드 서명은
  2. 방법은 정확히 동일한 순서로 나타나야합니다 호환되는 방식으로 일치해야합니다 상호 운용성 인터페이스의 올바른 구현의

    나의 이해는 주요 기준이 있다는 것입니다.

  3. 관리되지 않는 인터페이스가 다른 관리되지 않는 인터페이스에서 상속되는 경우 관리되는 구현은 먼저 기본 인터페이스에서 시작하여 기본 수준의 인터페이스 멤버를 선언해야합니다.

내 질문은; 가져올 인터페이스가 다른 인터페이스에서 상속 받았고 기본 인터페이스의 멤버 중 하나 이상을 무시하거나 숨기는 경우 멤버가 나타나는 순서와 관련하여 무엇을해야합니까? 인터페이스 멤버 선언은 어디에 있습니까? 첫째, 기본 인터페이스에서 선언 한 위치는 어디입니까? 또는 원래 위치에서 제거하고 파생 인터페이스가 선언 한 곳에 배치 할 수 있습니까? C# 코드에 대한 지금

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

는 :

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

답변

1

실제로이 작업을 수행하는 사람의 사례가 있습니까? COM에서 메서드와 인터페이스에서 파생 된 다른 메서드에서 동일한 메서드 이름을 사용하는 것은 COM에서 매우 합법적이지만 모든 개발 환경에서 파생 인터페이스를 사용하는 것이 어렵거나 불가능합니다. 여기에는 인터페이스를 기반으로 모든 COM 객체를 호출 할뿐만 아니라 구현도 포함됩니다.

COM 인터페이스에서 재정의 또는 숨김과 같은 것은 없습니다. COM 인터페이스는 객체의 바이너리 인터페이스가 메모리에 배치되는 방법에 대한 계약 일 뿐이며 인터페이스 정의의 메소드 이름은 도구를 제외하고는 의미가 없습니다. 귀하의 경우에 BaseComInterface는 'vtable'에 6 개의 메소드를 제공합니다. 처음 세 개는 IUnknown 메소드의 서명과 일치하고 다음 세 개는 사용자가 지정한 세 개의 메소드의 서명과 일치합니다. 모두 올바른 순서로 정렬됩니다. 반면에 DerivedComInterface는 9 개의 메소드를 포함하는 'vtable'을 약속합니다. 처음 세 개의 시그니처는 IUnknown 메소드와 일치하고, 다음 세 개의 시그니처는 BaseComInterface 메소드의 시그니처와 일치하며, 마지막 세 개의 시그니처는 DerivedComInterface에 고유 한 세 가지 메소드와 일치합니다. 이 메소드의 이름은 IDE, 도구 및 컴파일러에서 'vtable'포인터를 찾을 이름이 필요한 경우를 제외하고는 중요하지 않습니다.

기본적으로 C#과 C, C++ 및 다른 언어에서는 DerivedComInterface를 구현하기 위해 메소드 이름 중 하나를 다른 것과 'vtable'슬롯을 구별하기 위해 꾸밀 필요가 있습니다.

가 귀하의 질문에 대답하기 위해 - 그들은 모두 COM 계약을 이행 할 수있을 필요하기 때문에 당신은 어느 방법을 제거하는 것입니다 :

이이 인터페이스를 IDispatch보다는, IUnknown로부터 파생 된 경우 무슨 일이 일어날 지 무시
[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(); 
} 

, 내가 망설이고 싶지 않은 혼란. 또한 idl이 실제로 void를 반환하는 메서드를 정의하면 PreserveSig 특성을 사용하여 C# 메서드를 장식해야합니다.

+0

위대한 답변, 매우 유익한, 감사합니다! –

0

난 당신이 충돌을 피하기 위해 explicit interface member implementations를 사용하는 것이 좋습니다.

+0

나는이 질문을 읽지 않을 것이라고 생각합니다.여기에 interop 코드에 대해 이야기하고 있습니다. 순수한 관리 상속이 아닙니다. –

+0

그런데 C#으로 인터페이스를 구현하는 것에 대해 이야기하는 이유는 무엇입니까? 인터페이스는 다른 사람이 구현합니다. COM 개체의 RCW를 원하는 인터페이스로 캐스팅하면됩니다. .Net은 QueryInterface를 호출합니다. –

관련 문제