Я пытаюсь написать плагин для стороннего продукта. Это принимает форму родной C++ DLL, которая реализует указанный интерфейс из поставляемой библиотеки типов. Мой плагин загружается успешно, и методы, описанные интерфейсом, вызывают в ожидаемых точках, я могу записать файл журнала из моего плагина и запросить веб-службу, насколько это хорошо.COM Interop - Участник не найден
Однако, для моего плагина, который запрашивает основную программу, метод Initialize()
передает интерфейс IDispatch
. Я пытаюсь использовать этот интерфейс с некоторым кодом, как это:
Initialize(LPDISPATCH pDispArchivingControl) {
LPOLESTR ptName = L"currentVaultId";
HRESULT hr= pDispArchivingControl->GetIDsOfNames(IID_NULL, &ptName, 1,
LOCALE_USER_DEFAULT, &dispID);
// add parameters, etc
hr = pDispArchivingControl->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD, &dp, pvResult, NULL, NULL);
// hr = 0x80020003 Member not found.
}
Первая секция, GetIDsOfNames()
, делает то, что я думаю, что он должен, т.е. положить имена методов из документации программы в ptName
дает мне разные значения в dispID
- 15, 27 и так далее.
Второй раздел, Invoke()
, всегда возвращает HRESULT 0x80020003 (Member not found).
Я нашел некоторые решения, перечисленные здесь: HOWTO: Troubleshoot "Member Not Found" 0x80020003 Error. Для разрешения 1 я попробовал как DISPATCH_METHOD, так и DISPATCH_PROPERTYGET в качестве четвертого параметра. Правильно ли я предполагаю, что 2 и 3 не могут применяться ко мне, поскольку я возвращаю значения обратно в dispID? Я не уверен, как это изменить.
Теперь у меня есть идеи, и Google больше не помогает мне - может ли кто-нибудь предложить, что делать дальше?
ОБНОВЛЕНИЕ: Это то, что один из методов выглядит в оле. Я не мог найти его в TreeView, но смог открыть его с помощью File> View TypeLib ...
Не похоже на метод. Мы не можем видеть dp, это фактически индексированное свойство? Почему вы используете позднюю привязку, когда у вас есть библиотека типов? Посмотрите на него с Oleview.exe –
@HansPassant Я использую позднюю привязку, потому что я не знаю, что я делаю :) Я довольно новичок в C++ и COM. Я также попытался использовать #import с библиотекой типов, но не смог понять, как подключить к нему переданный интерфейс. Я попытался создать экземпляр и назначить ему интерфейс, который компилируется, но дает «недопустимый указатель» во время выполнения. Является ли #import лучше для этой ситуации? или что-то другое? –
Импорт должен создать интерфейс 'IArchivingControl' и, возможно, даже класс интеллектуальных указателей ATL' IArchivingControlPtr' ATL, если вам повезет. Если у вас есть умный указатель, просто попробуйте назначить ему IDispatch и посмотреть, получится ли у вас ненулевой объект, с которым вы можете позвонить. Если у вас нет умного указателя, попробуйте вызвать 'QueryInterface' в IDispatch с помощью IID_IArchivingControl и он должен создать для вас интерфейс IArchivingControl. Не забудьте «освободить» их обоих, когда закончите. – Rup