|
本帖发表于 2016-10-17 16:22:50...阅读 253 人...加油,亲爱的楼主:[db:作者]
前段时间开发了一个COM组件配合web前端使用,遇到了C++中调用JS代码的问题,在网上查了很多资料,现 总结一下,留作以后察看。
C++中调用JS代码主要有两种情况:1. IE线程中调用;2. 其他线程调用
1. IE线程中调用:这种情况网上已经有很多资料,下面列出示列代码:
C++代码
STDMETHODIMP CJsInvoker::InvokeJsFunc(LONG para1, LONG para2, VARIANT jsFunction, LONG*
retValue)
{
CComPtr[I] jsCallback;
if (jsFunction.vt == VT_DISPATCH)
jsCallback = jsFunction.pdispVal;
VARIANT arg[2];
arg[0].vt = VT_I4;
arg[1].vt = VT_I4;
arg[0].lVal = para1;
arg[1].lVal = para2;
VARIANT pvarRet;
jsCallback.InvokeN(static_cast(DISPID_VALUE), arg, 2, &pvarRet);
*retValue = pvarRet.lVal;
return S_OK;
}
JS代码
从代码中可以看出,Js方法作为IDispatch指针传入COM,C++通过调用其InvokeN 方法实现。
2. 其他线程调用:与IE线程直接调用的区别在于需要列集与反列集,原因是JS代码是运行 在自己的套间线程里的,其他线程是不能直接访问的,只能通过代理进入消息循环中。
C++代码
STDMETHODIMP CJsInvoker::InvokeJsFunc3(LONG para1, LONG para2, VARIANT jsFunction,
LONG* retValue)
{
// Check whether is valid Dispatch interface.
if (V_VT(&jsFunction) != VT_DISPATCH || jsFunction.pdispVal == NULL) {
return E_INVALIDARG;
}
// 对IDispatch指针列集
CoMarshalInterThreadInterfaceInStream(IID_IDispatch, jsFunction.pdispVal,
&m_stream_jsfunc);
m_hTread = CreateThread(NULL, 0, ThreadFunction, this, NULL, NULL);
return S_OK;
}
DWORD WINAPI ThreadFunction(LPVOID pParam)
{
::CoInitialize(NULL);
CJsInvoker* pJsInvoker = (CJsInvoker*)pParam;
CComPtr[I] script;
// 反列集得到IDisPatch指针
CoGetInterfaceAndReleaseStream(pJsInvoker->m_stream_jsfunc, IID_IDispatch, (LPVOID *)
&script);
VARIANT arg[2];
arg[0].vt = VT_I4;
arg[1].vt = VT_I4;
arg[0].lVal = 1;
arg[1].lVal = 2;
VARIANT pvarRet;
script.InvokeN(static_cast(DISPID_VALUE), arg, 2, &pvarRet);
::CoUninitialize();
return S_OK;
}
JS代码
|
|