My project is based on the ATL Browser sample.
In the HTML/JS part I have the following code:
function callBack(){
alert("Callback called!");
}
window.external.lengthyOperation(callBack);
In VC++ (6.0sp5) I do the following code:
struct WorkerThreadStuff{
VARIANT *pvCallback;
};
...
switch(dispidMember){
case DISPID_LENGTHYOPERATION:
DWORD dwThreadID;
WorkerThreadStuff *pStuff = new WorkerThreadStuff;
// Send JS function as VARIANT* to worker thread
pStuff->pvCallback = &(pDispParams->rgvarg[0]);
// Start thread
HANDLE hThread = CreateThread(NULL, 0, WorkerThreadFunc, pStuff, 0,
&dwThreadID);
return S_OK;
...
The worker thread is implemeted as follow:
DWORD WINAPI WorkerThreadFunc(LPVOID lpParameter){
HRESULT hr;
WorkerThreadStuff *pStuff = (WorkerThreadStuff*) lpParameter;
// Initialize COM
hr = CoInitialize(NULL);
// Get JS function from VARIANT* to IDispatch
CComPtr<IDispatch> spFunction(pStuff->pvCallback->pdispVal);
// No parameters are expected by the JS function
DISPPARAMS dispParams;
ZeroMemory(&dispParams, sizeof dispParams);
dispParams.cArgs = 0;
dispParams.rgvarg = NULL;
dispParams.cNamedArgs = 0;
// Initialize exception & return value
EXCEPINFO excepInfo;
ZeroMemory(&excepInfo, sizeof excepInfo);
CComVariant vaResult;
VariantInit(&vaResult);
// Initialize to invalid arg
UINT nArgErr = (UINT)-1;
// Call JS function
hr = spFunction->Invoke(DISPID_VALUE, IID_NULL, 0, DISPATCH_METHOD,
&dispParams, &vaResult, &excepInfo, &nArgErr);
// HERE IS THE PROBLEM:
// hr is always -2147418113 (Catastrophic failure)
// Unitialize COM
CoUninitialize();
return 0;
}
What am i doing wrong?
Thank you for your time.
You are passing a COM interface pointer across apartment boundaries
without marshalling. This is illegal in COM. You must either marshal the
pointer (see CoMarshalInterThreadInterfaceInStream,
CoGetInterfaceAndReleaseStream, or IGlobalInterfaceTable), or switch
back to the main thread before using the callback (e.g. by posting a
user-defined window message to some window running on the main thread).
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925
Right on spot! CoMarshalInterThreadInterfaceInStream /
CoGetInterfaceAndReleaseStream did the trick.
Thank you very much for your quick and exact response.
Aren't you getting tired of being right all the time? :)