, где я возвращаю адрес методов моего класса. И хотя я не знаю, как получить адрес метода класса, он, безусловно, отвечает на мой вопрос: «Как CreateStdDispatch« знает, как вызывать мои методы? ». Ответ заключается в том, что я даю ему адреса функций (предположительно относительно начала объекта).
лкнулся с реализацией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;
Не желая писать весь утомительный шаблонный код, который, я уверен, будет содержать ошибки, я занялся поиском, а не выполнял какую-либо работу.
я нашел этот фрагмент наДокументация MSDNIDispatch.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 APICreateStdDispatch
знает, какие методы нужно вызывать на моем объекте, особенно еслиCreateStdDispatch
не знает, какой объектно-ориентированный язык я использую, или его соглашения о вызовах.
Как будетCreateStdDispatch
знать
dispid
?соглашение о вызовах моего языка?Как обрабатывать исключения из языка, на котором написан мой объектно-ориентированный объект?Запись: у меня нет выбора, кроме как реализоватьdispinterface
; я не определилинтерфейс, Я хотел бы, чтобы это было просто раноIUnknown
Но это не так.