Разрешение конфликтов имен функций и свойств в службе автоматизации в расширениях
В этом разделе "объект" указывает объект в целом, как клиент 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.
Дополнительные сведения о разрешении конфликтов имен см. в разделе "Пример разрешения конфликтов имен функций".