다음을 통해 공유


Automation에서 초기 바인딩 및 늦은 바인딩 사용

요약

Automation 서버에 바인딩하는 방법은 성능, 유연성 및 유지 관리 기능과 같은 프로그램의 많은 항목에 영향을 줄 수 있습니다.

이 문서에서는 Automation 클라이언트에서 사용할 수 있는 바인딩 유형에 대해 설명하고 각 메서드의 양쪽에 무게를 줍니다.

추가 정보

Automation은 한 소프트웨어 구성 요소가 Microsoft의 COM(구성 요소 개체 모델)을 사용하여 다른 소프트웨어 구성 요소와 통신하거나 제어하는 프로세스입니다. Visual Basic 또는 Visual Basic for Applications 같은 언어에서 사용되는 대부분의 구성 요소 간 통신의 기초이며 대부분의 프로그램에서 정상적인 부분이 되었습니다.

지금까지 Automation 개체는 IDispatch 인터페이스를 지원하는 모든 개체입니다. 이 인터페이스를 사용하면 클라이언트가 디자인 타임에 통신하는 정확한 개체를 알 필요 없이 런타임에 메서드 및 속성을 호출할 수 있습니다. 지연 바인딩이라는 프로세스입니다. 그러나 오늘날에는 IDispatch를 지원하지 않는 경우에도 거의 모든 COM 개체에 Automation 개체라는 용어를 적용할 수 있습니다(따라서 늦게 바인딩될 수 없음). 이 문서에서는 자동화하는 개체가 두 바인딩 메서드를 모두 지원한다고 가정합니다.

바인딩이란?

바인딩은 프로그래머가 작성한 함수 호출을 함수를 구현하는 실제 코드(내부 또는 외부)와 일치시키는 프로세스입니다. 애플리케이션이 컴파일될 때 수행되며 코드에서 호출된 모든 함수를 바인딩해야 코드를 실행할 수 있습니다.

이 과정을 이해하려면 책을 출판하는 측면에서 "바인딩"을 생각해 보십시오. 코드가 특정 단락에서 "12장, 자세한 내용은 x페이지 참조"와 같이 작성한 책의 텍스트와 같다고 상상해 보십시오. 책이 끝날 때까지 페이지 번호가 무엇인지 알 수 없으므로 단락을 의도한 대로 읽기 전에 책의 모든 페이지와 단락에 삽입된 올바른 페이지 번호를 함께 바인딩해야 합니다. 책의 다른 부분을 참조하기 전에 책이 "바인딩"될 때까지 기다립니다.

바인딩 소프트웨어는 비슷합니다. 코드는 코드를 "읽기" 전에 함께 끌어와야 하는 부분으로 구성됩니다. 바인딩은 함수가 호출될 때 코드가 "이동"되는 메모리 주소(또는 메모리 오프셋)로 함수 이름을 바꾸는 작업입니다. COM 개체의 경우 주소는 개체가 보유한 포인터 테이블(v-table이라고 함)의 메모리 오프셋입니다. COM 함수가 바인딩되면 v-테이블을 통해 바인딩됩니다.

COM 개체의 구조는 간단합니다. 코드가 개체에 대한 참조를 보유하는 경우 v-테이블의 맨 위에 대한 간접 포인터를 보유합니다. v-table은 각 항목이 해당 개체에서 호출할 수 있는 다른 함수인 메모리 주소의 배열입니다. COM 개체에서 세 번째 함수를 호출하려면 테이블의 세 항목을 아래로 이동한 다음 지정된 메모리 위치로 이동합니다. 그러면 함수에 대한 코드가 실행되고, 완료되면 다음 코드 줄을 실행할 준비가 된 것으로 돌아갑니다.

+-[Code]------------+  +.................................[COM Object]...+
|                   |  : +-------------+                                :
|Set obj = Nothing -|--->| obj pointer |                                :
|                   |  : +-|-----------+                                :
+-------------------+  :   |   +-----------------+                      :
                       :   +-->| v-table pointer |                      :
                       :       +--|--------------+                      :
                       :          |                                     :
                       :          |  +----------------------------+     :
                       :  (3rd)   |  | Function 1 Address pointer |     :
                       : (Offset) |  +----------------------------+     :
                       :          |  | Function 2 Address pointer |     :
                       :          |  +----------------------------+     :
                       :          +->| Function 3 Address pointer |     :
                       :             +----------------------------+     :
                       +................................................+

위의 예제에서는 COM 개체를 해제할 때 발생하는 동작을 보여줍니다. 모든 COM 개체가 IUnknown에서 상속되므로 테이블의 처음 세 항목은 IUnknown에 대한 메서드입니다. 개체를 해제해야 하는 경우 코드는 v-table(IUnknown::Release)의 세 번째 함수를 호출합니다.

다행히 이 작업은 백그라운드에서 Visual Basic에 의해 수행됩니다. Visual Basic 프로그래머로서 V 테이블을 직접 처리할 필요가 없습니다. 그러나 이 구조는 모든 COM 개체가 바인딩되는 방식이며 바인딩이 무엇인지 이해하는 데 익숙한 것이 중요합니다.

초기 바인딩

위의 예제는 초기(또는 v 테이블) 바인딩이라고 합니다. 모든 COM 개체의 경우 이 형식의 바인딩은 COM 개체의 IUnknown 인터페이스를 호출할 때마다 발생합니다. 그러나 개체의 다른 함수는 어떻습니까? Refresh 메서드 또는 Parent 속성을 어떻게 호출하나요? 이러한 함수는 일반적으로 개체에 고유한 사용자 지정 함수입니다. v-table의 해당 위치를 가정할 수 없는 경우 호출에 필요한 함수 주소를 어떻게 찾을 수 있나요?

물론 대답은 개체의 v-table이 어떻게 표시되는지 미리 알고 있는지 여부에 따라 달라집니다. 이렇게 하면 IUnknown 메서드와 동일한 초기 바인딩 프로세스를 개체의 사용자 지정 메서드에 수행할 수 있습니다. 이는 일반적으로 "조기 바인딩"을 의미합니다.

개체에서 초기 바인딩을 사용하려면 해당 v 테이블의 모양을 알고 있어야 합니다. Visual Basic에서는 개체, 해당 인터페이스(v-table) 및 개체에서 호출할 수 있는 모든 함수를 설명하는 형식 라이브러리에 대한 참조를 추가하여 이 작업을 수행할 수 있습니다. 이 작업이 완료되면 개체를 특정 형식으로 선언한 다음 v-table을 사용하여 해당 개체를 설정하고 사용할 수 있습니다. 예를 들어 초기 바인딩을 사용하여 Microsoft Office Excel을 자동화하려는 경우 프로젝트에서 "Microsoft Excel 8.0 개체 라이브러리"에 대한 참조를 추가합니다| 대화 상자를 참조한 다음 변수를 "Excel.Application" 형식으로 선언합니다. 그 때부터 개체 변수에 대한 모든 호출은 초기 바인딩됩니다.


' Set reference to 'Microsoft Excel 8.0 Object Library' in
' the Project|References dialog (or Tools|References for VB4 or VBA).

' Declare the object as an early-bound object
  Dim oExcel As Excel.Application

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via the v-table
  oExcel.Visible = True

이 메서드는 대부분의 시간 동안 잘 작동하지만 디자인 타임에 사용할 정확한 개체를 모르는 경우 어떻게 해야 할까요? 예를 들어 여러 버전의 Excel 또는 "알 수 없는" 개체와 완전히 통신해야 하는 경우 어떻게 해야 할까요?

지연 바인딩

COM에는 IDispatch가 포함되어 있습니다. IDispatch를 구현하는 개체에는 dispinterface(지원하는 유일한 인터페이스인 경우) 또는 이중 인터페이스(초기 바인딩할 수 있는 사용자 지정 인터페이스가 있는 경우)가 있다고 합니다. IDispatch에 바인딩하는 클라이언트는 호출하는 정확한 속성 또는 메서드가 IDispatch 메서드를 사용하여 런타임에 결정되므로 "지연 바인딩"이라고 합니다. 이전 책 예제로 돌아가서, 이미 텍스트에 인쇄하지 않고 "읽기 시간"에 페이지 번호를 "조회"해야 하는 목차로 안내하는 각주와 같다고 생각합니다.

인터페이스의 마법은 GetIDsOfNames 및 Invoke라는 두 가지 함수에 의해 제어됩니다. 첫 번째는 함수 이름(문자열)을 함수를 나타내는 식별자(dispid라고 함)에 매핑합니다. 호출하려는 함수의 ID를 알게 되면 Invoke 함수를 사용하여 호출할 수 있습니다. 이 형식의 메서드 호출을 "지연 바인딩"이라고 합니다.

다시 말하지만, Visual Basic에서는 개체가 바인딩되는 방식을 개체 선언에 의해 지정합니다. 개체 변수를 "Object"로 선언하면 실제로 Visual Basic에 IDispatch를 사용하도록 알려주므로 바인딩이 늦습니다.

' No reference to a type library is needed to use late binding.
' As long as the object supports IDispatch, the method can 
' be dynamically located and invoked at run-time.

' Declare the object as a late-bound object
  Dim oExcel As Object

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via IDispatch
  oExcel.Visible = True

보듯이 코드의 나머지 부분도 동일합니다. 초기 바인딩과 지연 바인딩 간의 유일한 차이점은(작성하는 코드 측면에서) 변수 선언에 있습니다.

"지연 바인딩"은 호출되는 방식이 아니라 호출되는 함수라는 점에 유의해야 합니다. 일반적으로 바인딩에 대한 이전 설명에서 IDispatch 자체는 "초기 바인딩:"입니다. 즉, Visual Basic은 COM 호출과 마찬가지로 V 테이블 항목(IDispatch::Invoke)을 통해 Visible 속성을 설정하기 위해 호출합니다. COM 개체 자체는 호출을 올바른 함수로 전달하여 Excel을 표시합니다. 이 간접 참조를 사용하면 Visual Basic 클라이언트를 컴파일할 수 있지만(즉, 유효한 함수 주소에 바인딩됨) 실제로 작업을 수행할 정확한 함수는 아직 알 수 없습니다.

Dispid 바인딩

일부 Automation 클라이언트(가장 눈에 띄게 MFC 및 Visual Basic 3.0뿐만 아니라 ActiveX 컨트롤과 관련된 Visual Basic 5.0 및 6.0)는 dispid 바인딩이라는 하이브리드 형식의 늦은 바인딩을 사용합니다. 디자인 타임에 COM 개체가 알려진 경우 호출되는 함수에 대한 dispids를 캐시하고 런타임에 GetIDsOfNames를 호출할 필요 없이 IDispatch::Invoke에 직접 전달할 수 있습니다. 함수당 두 개의 COM 호출을 만드는 대신 하나만 호출하면 되므로 성능이 크게 향상됩니다.

Dispid 바인딩은 일반적으로 Visual Basic 5.0 또는 6.0에서 선택할 수 있는 옵션이 아닙니다. 형식 라이브러리에서 참조되지만 사용자 지정 인터페이스(즉, dispinterface만 있는 개체의 경우)를 포함하지 않는 개체 및 집계된 ActiveX 컨트롤에 사용되지만 일반적으로 Visual Basic은 dispid 바인딩을 사용하는 모든 위치를 초기 바인딩을 사용합니다.

어떤 형식의 바인딩을 사용해야 하나요?

이 질문에 대한 대답은 프로젝트의 디자인에 따라 달라집니다. Microsoft는 거의 모든 경우에 초기 바인딩을 권장합니다. 그러나 늦은 바인딩을 선택하는 데는 이유가 있을 수 있습니다.

초기 바인딩이 기본 설정 방법입니다. 애플리케이션이 호출되는 함수의 주소에 직접 바인딩되고 런타임 조회를 수행하는 데 추가 오버헤드가 없기 때문에 최상의 성능입니다. 전체 실행 속도의 관점에서, 그것은 적어도 두 배 빠른 바인딩입니다.

초기 바인딩은 형식 안전성도 제공합니다. 구성 요소의 형식 라이브러리에 대한 참조 집합이 있는 경우 Visual Basic은 각 함수를 올바르게 코딩하는 데 도움이 되는 IntelliSense 지원을 제공합니다. 또한 Visual Basic은 매개 변수 또는 반환 값의 데이터 형식이 올바르지 않으면 경고하여 코드를 작성하고 디버깅할 때 많은 시간을 절약할 수 있습니다.

지연 바인딩은 디자인 타임에 개체의 정확한 인터페이스를 알 수 없는 경우에도 여전히 유용합니다. 애플리케이션이 알 수 없는 여러 서버와 통신하려고 하거나 이름으로 함수를 호출해야 하는 경우(예: Visual Basic 6.0 CallByName 함수 사용) 늦은 바인딩을 사용해야 합니다. 지연 바인딩은 버전 간에 인터페이스를 잘못 수정하거나 조정한 구성 요소의 여러 버전 간의 호환성 문제를 해결하는 데에도 유용합니다.

초기 바인딩에 주어진 이점은 가능하면 최상의 선택입니다.

여러 버전에서 호환성 유지 관리

설치 패키지와 함께 재배포하지 않는 구성 요소를 사용하고 런타임에 통신할 정확한 버전을 확신할 수 없는 경우 모든 버전의 구성 요소와 호환되는 인터페이스에 대한 조기 바인딩에 특별한 주의를 기울이거나(경우에 따라) 특정 버전에 존재할 수 있는 메서드를 호출하고 해당 메서드가 정상적으로 실패하는 경우 지연 바인딩을 사용해야 합니다. 는 클라이언트 시스템에 설치된 버전에 없습니다.

Microsoft Office 애플리케이션은 이러한 COM 서버의 좋은 예를 제공합니다. Office 애플리케이션은 일반적으로 인터페이스를 확장하여 새 기능을 추가하거나 버전 간의 이전 단점을 수정합니다. Office 응용 프로그램을 자동화해야 하는 경우 클라이언트 시스템에 설치할 수 있을 것으로 예상되는 제품의 초기 버전에 조기에 바인딩하는 것이 좋습니다. 예를 들어 Excel 95, Excel 97, Excel 2000 및 Excel 2002를 자동화할 수 있어야 하는 경우 Excel 95용 형식 라이브러리(XL5en32.olb)를 사용하여 세 가지 버전 모두와의 호환성을 유지해야 합니다.

또한 Office 애플리케이션은 큰 이중 인터페이스가 있는 개체 모델이 일부 플랫폼에서 마샬링에 제한을 받을 수 있음을 보여 줍니다. 코드가 모든 플랫폼에서 가장 잘 작동하려면 IDispatch를 사용합니다.

참조

COM, v 테이블 및 Automation 사용에 대한 자세한 내용은 다음 책을 참조하세요.

로저슨, 데일, 인사이드 COM, MSPRESS, ISBN: 1-57231-349-8.

Curland, Matt, Advanced Visual Basic 6, DevelopMentor, 0201707128.