다음을 통해 공유


함수 이름 충돌 해결 예제

다음을 살펴보세요.

  • IADs0은 Func0을 지원하지 않습니다.
  • IADs1은 Func1 및 Func0을 지원합니다.
  • IADs2는 Func2 및 Func0을 지원합니다.

세 인터페이스는 모두 이중 인터페이스입니다.

IADs0 : IDispatch
{
    OtherFunc();
}

IADs1 : IDispatch
{
    Func0() 
    Func1();
}

IADs2 : IDispatch
{
    Func0()
    Func2();
}
Dim myInf1 as IADs1
 
myInf1.Func1  ' IADs1::Func1 is invoked using direct vtable access 
 
myInf1.Func2  ' IADs2::Func2 is invoked using GetIDsOfNames/Invoke

IADs1이 Func2를 지원하지 않더라도 ADSI 클라이언트는 모델의 모든 이중 및 디스패치 인터페이스를 지원하는 하나의 IDispatch 를 인식합니다. 따라서 ADSI 클라이언트는 Func2를 지원하는 인터페이스를 해결하지 않고 myInf1.Func2를 사용하여 Func2를 직접 호출할 수 있습니다.

myInf1.Func2

IADs1과 IADs2에는 모두 Func0이라는 함수가 있지만 IADs1::Func0은 vtable 액세스를 사용하여 직접 호출됩니다. 두 가지 모두 클라이언트에 적용되기 때문입니다.

  • 클라이언트에는 Func0이라는 함수가 있는 이중 인터페이스 IADs1 개체에 대한 포인터가 있습니다.
  • Visual Basic은 형식 라이브러리를 통해 데이터 형식을 사용할 수 있다고 가정하여 직접 vtable 액세스를 지원합니다.

다음 코드 예제에서 클라이언트에는 IADs1 대신 IADs2에 대한 이중 인터페이스 포인터가 있습니다. 따라서 IADs2::Func0은 직접 vtable 액세스를 사용하여 호출됩니다.

Dim myInf2 as IADs2
Set myInf2 = myInf1 ' Query for pointer to IADs2 
myInf2.Func0

다시 말하지만, 다음 코드 예제에서 IADs1과 IADs2에는 Func0이라는 함수가 있지만 여기서 클라이언트에는 Func0이라는 함수가 없는 이중 인터페이스 IADs0에 대한 포인터가 있습니다. 따라서 직접 vtable 액세스를 수행할 수 없습니다. 대신 IDispatch::GetIDsOfNamesInvoke 가 호출되어 Func0을 호출합니다.

Dim myInfNone as IADs0
Set myInfNone = myInf1    ' The aggregated object that 
   ' supports IADs1 and IADs2.
myInfNone.Func0

다음 두 가지 경우를 고려합니다.

  • IADs1 및 IADs2는 각각 두 개의 COM 구성 요소인 Ext1 및 Ext2에 의해 구현됩니다. Ext1이 레지스트리의 Ext2 앞에 오면 IADs1::Func0이 호출됩니다. 그러나 Ext2가 레지스트리에서 먼저 제공되면 IADs2::Func0이 호출됩니다.
  • IADs1 및 ADs2가 동일한 확장 개체에 의해 구현되는 경우 Func0은 항상 확장의 IADsExtension::P rivateGetIDsOfNamesPrivateInvoke 메서드에 의해 호출됩니다.

확장 개발자는 확장에 이름이 같은 서로 다른 이중 IDispatch 인터페이스의 함수 또는 속성 충돌을 resolve 방법을 결정해야 합니다. IADsExtension::P rivateGetIDsOfNamesPrivateInvoke 메서드의 구현은 이 충돌을 resolve 합니다. 예를 들어 IMyInterface1::Func1 및 IMyInterface2::Func1을 사용하는 경우 IMyInterface1 및 IMyInterface2는 동일한 확장 개체에서 지원하는 이중 IDispatch 인터페이스입니다. PrivateGetIDsOfNamesPrivateInvoke 메서드는 항상 호출해야 하는 Func1을 결정해야 합니다.

다른 이중 또는 IDispatch 인터페이스의 충돌하는 DISPID도 마찬가지입니다.

예를 들어 IMyInterface1::Y의 DISPID는 imyinterface1.odl 파일 또는 imyinterface1.idl의 2입니다. IMyInterface2::X의 DISPID는 iMyInterface2.odl에서도 2입니다. IADsExtension::P rivateGetIDsOfNames 는 둘 다에 대해 동일한 DISPID를 반환하는 대신 각각에 대해 확장 자체 내에서 고유한 DISPID를 반환해야 합니다.

ADSI는 함수 또는 속성 이름이 충돌하는 여러 인터페이스를 지원하지 않음으로써 첫 번째 문제를 해결합니다. DISPID의 사용되지 않는 비트에 동일한 확장 개체, 인터페이스 번호 내에 있는 고유한 을 추가하여 두 번째 문제를 해결합니다.