I'm try to write a plugin for a 3rd party product. This takes the form of a native C++ DLL, which implements a specified interface from a supplied type library. My plugin is getting loaded successfully, and the methods described by the interface are being called at the expected points, I can write out a log file from my plugin and query a web service, so far so good.
However, for my plugin to query the main program, the Initialize()
method passes an IDispatch
interface. I'm attempting use this interface with some code like this:
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.
}
The first section, GetIDsOfNames()
, does what I think it should, i.e. putting the names of methods from the program's documentation into ptName
gives me different values in dispID
- 15, 27, and so on.
The second section, Invoke()
, always returns HRESULT 0x80020003 (Member not found).
I found some solutions listed here: HOWTO: Troubleshoot "Member Not Found" 0x80020003 Error. For resolution 1, I tried both DISPATCH_METHOD and DISPATCH_PROPERTYGET as the fourth parameter. Am I right in assuming 2 and 3 cannot apply to me as I am getting the values back in dispID? I'm not sure how to change these either.
I've kinda out of ideas now, and Google is not helping me any further - can anyone suggest what to do next?
UPDATE: This is what one of the methods looks like in oleview. I couldn't find it in the treeview but was able to open it with File > View TypeLib...
The correct answer to this question, given by Hans Passant and Rup in the comments, is not to use late binding, but to #import
the type library.
I put this in stdafx.h
:
#import "ArchivingControl.tlb" raw_interfaces_only, raw_native_types, named_guids, auto_search
And this in my .cpp file:
ArchivingControl::IArchivingControlPtr JTArchivingControlPtr;
STDMETHODIMP CMyClass::Initialize(LPDISPATCH pDispArchivingControl)
{
JTArchivingControlPtr = pDispArchivingControl;
return S_OK;
}
STDMETHODIMP CMyClass::OtherFunction()
{
BSTR pVaultId;
JTArchivingControlPtr->get_currentVaultId(&pVaultId);
return S_OK;
}
And now everything works nicely, plus I have way less code now - Thanks!
User contributions licensed under CC BY-SA 3.0