2017-04-03 4 views
0

다른 인터페이스를 반환하는 COM 인터페이스에서 메서드를 호출하면 punkVal이 매번 달라집니다.COM 인터페이스가 동일한 호출 메소드에 대해 다른 값을 반환하는 이유는 무엇입니까?

그러나 이전 punkVal 's를 사용하여 해당 인터페이스 메소드를 호출해도 작동합니다. 불필요한 객체 (또는 객체에 대한 포인터)가 많이 생성되는 것 같지만 반환 된 인터페이스가 고유한지 여부를 결정하려면 다소 필요합니다. 내가 알기로는 인터페이스 (punkVal)를 리턴하고 모든 인스턴스마다 값이 다르다는 것입니다. 그 값이 가리키는 값은 항상 같지만 vtable 또는 무언가를 가리키고 있기 때문에 믿을만한 수표가 아닌 것 같습니다. 그것, 또는 이질적으로 보이는 인터페이스조차 실제로 모두 동일한 인터페이스입니다.

은 명확합니다 :

someCOMInterface foo(); 

내가 foo는에 호출하고 punkVal가 나중에 쿼리가 호출 사용 방법의 호출해야한다 someCOMInterface 될 것으로 예상 호출합니다. 하지만 첫 번째 호출을 호출 할 때마다 다른 someCOMInterface (호출이 반환 한 값에서 "동일"하지만 "다름")을 얻습니다.

답변

1

이것은 흔하지 않습니다. 동일한 메서드에 대한 여러 호출에서 반환 된 인터페이스 포인터가 동일한 포인터를 반환하는지 여부는 전적으로 COM 라이브러리의 개발자에게 달려 있습니다.

다른 포인터가 반환 될 수있는 이유 중 하나는 특정 COM 라이브러리 내에서 사용되는 핵심 개체 모델이 COM이 아닐 수 있다는 것입니다. 예를 들어, shared_ptr 같은 것들을 사용하여 C++로 객체 모델을 작성했습니다. 아마도 C++ 클라이언트를위한 더 나은 객체 모델이 될 것입니다. 그러나 C++ 객체 모델을 상호 운용성에 노출 (또는 더 일반적으로 DLL로 노출)하면 COM이 더 나은 선택이 될 수 있습니다. 복잡하고 계층 적 인 객체 모델을 래퍼 클래스 집합과 동기화하여 유지하는 것은 어렵 기 때문에 래퍼 객체는 일시적 일 수 있습니다. 필요에 따라 작성되고 클라이언트가 더 이상 사용하지 않을 때마다 파기됩니다.

이러한 상황에서 클라이언트는 여전히 개체가 "동등"하다는 것을 알아야 할 수도 있습니다. 동일한 내부 개체를 래핑하는 두 개의 서로 다른 개체를 "균등"하게 간주 할 수 있습니다. 이를 확인하기 위해 Microsoft는 IObjectEquality 인터페이스를 정의합니다. 이 인터페이스는 클라이언트가 명시 적으로 두 개의 같지 않은 포인터가 개념적으로 "같음"객체인지 여부를 확인할 수 있도록 COM 래퍼 클래스에 의해 구현 될 수 있습니다. 사용중인 객체는이 인터페이스를 구현할 수도 있고 구현하지 않을 수도 있습니다. This blog post은이 인터페이스를 사용하여 객체 평등을 결정하는 완전한 예를 보여줍니다.

IObjectEquality이 구현되지 않은 경우 일반적으로 Name 또는 ID 또는 기타 식별 속성을 제공하여 이러한 결정을 내리는 데 필요한 방법을 제공하는 것은 COM 개체 개발자의 몫입니다. 예를 들어 Excel의 Application.Range 속성은 동일한 인수를 사용하여 후속 호출에서 다른 포인터를 반환합니다. 두 범위가 같은지 확인하려면 Range.Address 메서드를 사용하여 해당 범위의 "식별자"를 가져온 다음 해당 식별자를 비교할 수 있습니다.