Поделиться через


Разрешение конфликтов имен функций и свойств в службе автоматизации в расширениях

В этом разделе "объект" указывает объект в целом, как клиент ADSI его просматривает. То есть, ADSI и все его расширения.

То же имя функции с теми же параметрами

Если два или более двух интерфейсов IDispatch в объекте поддерживают свойство или метод одного и того же имени, например Func1, вызов определяется с помощью следующих критериев. Если клиент имеет указатель на один из двух интерфейсов, поддерживающих метод Func1, и если доступ к vtable поддержка среды automation поддержка среды s, Func1 вызывается непосредственно через доступ к vtable ADSI.

Если любой из указанных выше условий имеет значение false, вызывается IDispatch::GetIDsOfNames и IDispatch::Invoke для вызова Func1.

Дополнительные сведения и краткое описание того, как клиент может добавить указатель на двойной интерфейс, а также описание типов сред, поддерживающих доступ к vtable, см. в разделе "Поздняя привязка" и "Vtable Access" в модели расширения ADSI.

Так как все объекты расширения перенаправляют функции IDispatch обратно в агрегатор, агрегатор управляет вызовом Func1. Ниже приведены правила.

  • Если какой-либо интерфейс, а в агрегаторе (ADSI) будет использоваться только один интерфейс, то агрегатор вызывает собственный Func1.
  • В противном случае агрегатор проходит через каждое из его расширений в порядке, указанном в реестре, и находит первое расширение, реализующее функцию с именем Func1. Возможно, но маловероятно, что несколько двух интерфейсов IDispatch в этом первом расширении имеют функцию Func1. Расширение должно определять, какой func1 всегда должен вызываться в службе автоматизации.

Одно и то же имя функции с разными параметрами

В предыдущем разделе описано, как разрешать конфликты имен функций, то есть имена функций с одинаковым именем функции и таким же списком параметров, например числом, типом и порядком при возникновении в службе автоматизации. Что делать, если две функции имеют одно и то же имя, но разные параметры? Если клиент ADSI вызывает функцию с помощью IDispatch::GetIDsOfNames без использования нескольких имен для указания параметров, модель расширения ADSI не может диффегировать функции. На основе схемы разрешения, описанной выше, первое расширение в реестре, поддерживающее эту функцию через один из интерфейсов, имеет свою версию этой функции, и вызов может завершиться ошибкой или привести к неправильным результатам.

Например:

  • Extn1 (первый в реестре под ЦС класса — более высокий приоритет) поддерживает IInterface1.
  • Extn2 (третий в реестре под ЦС класса — более низкий приоритет) поддерживает IInterface2.
  • IInterface1 поддерживает Method1(int param1, int param2).
  • IInterface2 поддерживает Method1(int param1).

Клиент ADSI имеет указатель интерфейса IDispatch на объект ЦС класса. Он хочет вызвать IInterface2::Method1. Если клиент вызывает pDispatch-GetIDsOfNames>(IID_NULL, rgszNames, 1, MY_LCID, rgDispId)), просто сохраняя имя функции "Method1" в rgszNames[0], то iInterface1::Method1 вместо требуемого IInterface2::Method1 вызывается, а функция завершается ошибкой, так как число параметров отличается.

Чтобы свести к минимуму эту проблему, разработчики расширений могут префиксировать имена функций с собственными идентификаторами и избегать проектов интерфейсов, использующих функции одного и того же имени, но разные параметры.

Если конфликт имен возникает, клиенты ADSI могут избежать проблемы путем прямого доступа к vtable, если интерфейс является двойным интерфейсом. Если прямой доступ к vtable невозможен, клиенты ADSI должны вызывать IDispatch::GetIDsOfNames с несколькими именами, указав имена функций, а также параметры массива rgszNames, описанные ранее.

Visual Basic 5 не вызывает функцию IDispatch::GetIDsOfNames с несколькими именами. То есть он передает только имя функции в GetIDsOfNames, но не аргументы. Однако Visual Basic 5 позволяет пользователям вызывать функцию путем прямого доступа к vtable, а не вызывать функцию IDispatch::GetIDsOfNames , если интерфейс является двойным интерфейсом. Если это возможно, разработчики должны использовать прямой доступ к vtable.

Дополнительные сведения о разрешении конфликтов имен см. в разделе "Пример разрешения конфликтов имен функций".