Как CreateStdDispatch знает, какой метод вызывать? - PullRequest
4 голосов
/ 28 июня 2011

Я столкнулся с реализацией интерфейса IDispatch. Есть четыре метода, и, к счастью, 3 из них просты:

function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetTypeInfo(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetIDsOfNames(...): HResult;
{
   Result := E_NOTIMPL;
}

Это последний метод, Invoke, который сложен. Здесь я сталкиваюсь с необходимостью на самом деле указать DispID и вызвать мой соответствующий метод; Снятие параметров с альтернативного массива.

function Invoke(  
  dispIdMember: DISPID;
  riid: REFIID;
  lcid: LCID;
  wFlags: WORD;
  var pDispParams: DISPPARAMS;
  var pVarResult: VARIANT;
  var pExcepInfo: EXCEPINFO;
  var puArgErr: DWORD
): HRESULT;

Не желая писать весь утомительный шаблонный код, который, я уверен, будет содержать ошибки, я стал гуглить, а не выполнять какую-либо работу.

Я нашел этот фрагмент в Документации MSDN IDispatch.Invoke:

Как правило, вы не должны реализовывать Invoke напрямую.

Отлично! я не хотел реализовывать это так или иначе! Продолжение чтения:

Вместо этого используйте интерфейс диспетчеризации для создания функций CreateStdDispatch и DispInvoke . Подробнее см. CreateStdDispatch , DispInvoke , Создание интерфейса IDispatch и Предоставление объектов ActiveX .

Ссылка Создание интерфейса IDispatch говорит:

Вы можете реализовать IDispatch любым из следующих способов:

  • [надрез]
  • Вызов функции CreateStdDispatch . Этот подход является самым простым, но он не предусматривает расширенной обработки ошибок или нескольких национальных языков.
  • [надрез]

Отлично, CreateStdDispatch Это:

Создает стандартную реализацию интерфейса IDispatch посредством одного вызова функции. Это упрощает экспонирование объектов с помощью автоматизации.

HRESULT CreateStdDispatch(  
  IUnknown FAR*  punkOuter,        
  void FAR*  pvThis,               
  ITypeInfo FAR*  ptinfo,          
  IUnknown FAR* FAR* ppunkStdDisp  
);

я собирался назвать это как:

CreateStdDispatch(
    myUnk,          //Pointer to the object's IUnknown implementation.
    anotherObject,  //Pointer to the object to expose.
    nil             //Pointer to the type information that describes the exposed object (i has no type info)
    dispInterface   //the IUnknown of the object that implements IDispatch for me
);

Что я не могу понять, так это то, как реализация Windows 10 CreateStdDispatch знает, какие методы нужно вызывать для моего объекта, тем более что CreateStdDispatch не знает, какой объектно-ориентированный язык я использую, или его соглашения о вызовах. .

Как CreateStdDispatch узнает

  • какой метод вызывать для данного dispid?
  • соглашение о вызовах моего языка?
  • как обрабатывать исключения из языка, на котором написан мой объектно-ориентированный объект?

Примечание : у меня нет выбора, кроме как реализовать dispinterface; я не определил интерфейс . Я хотел бы, чтобы это был простой ранний предел IUnknown, но это не так.

1 Ответ

4 голосов
/ 28 июня 2011

Разве параметр ITypeInfo, переданный в CreateStdDispatch, не предоставляет всю информацию о методе?

Таким образом, вы сначала создадите информацию о типе, вызывая CreateDispTypeInfo, и передадите ее через CreateStdDispatch, которая затем может использовать информацию о типе, чтобы определить, какой метод вызывать, поскольку CreateDispTypeInfo требует INTERFACEDATA, который содержитвся эта информация

Я могу ошибаться, потому что у меня нет времени на ее изучение, но для меня это имеет смысл.Я исследую это позже и обновлю ответ.

...