JavaScript调用C++函数
来源:互联网 发布:linux系统如何上网 编辑:程序博客网 时间:2024/06/05 15:15
上篇介绍了用C++调用JavaScript,这篇反过来说说JS调C++,这样JS和C++沟通的途径就完整了。
首先,实现一个IDispatch接口,当JS调用C++函数时,系统会调用GetIDsOfNames来用函数名取得函数的DISPID,然后调用Invoke完成真正的调用,需要注意的是Invoke的pDispParams中的参数是倒序的。代码如下:
- class CExtenalDispatch : public IDispatch
- {
- public:
- CExtenalDispatch()
- {
- m_dwRef = 0;
- }
- ~CExtenalDispatch()
- {
- }
- STDMETHOD_(ULONG, AddRef)()
- {
- return InterlockedIncrement(&m_dwRef);
- }
- STDMETHOD_(ULONG, Release)()
- {
- unsigned long l = InterlockedDecrement(&m_dwRef);
- if(l == 0)
- delete this;
- return l;
- }
- STDMETHOD(QueryInterface)(REFIID iid, LPVOID far* ppvObject)
- {
- HRESULT hrRet = S_OK;
- *ppvObject = NULL;
- if(IsEqualIID(iid, IID_IDispatch))
- *ppvObject = (IDispatch*)this;
- else
- hrRet = E_NOINTERFACE;
- if (S_OK == hrRet)
- ((IUnknown*)*ppvObject)->AddRef();
- return hrRet;
- }
- STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
- {
- return E_NOTIMPL;
- }
- STDMETHOD(GetTypeInfo)(/* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ ITypeInfo** ppTInfo)
- {
- return E_NOTIMPL;
- }
- STDMETHOD(GetIDsOfNames)(
- /* [in] */ REFIID riid,
- /* [size_is][in] */ LPOLESTR *rgszNames,
- /* [in] */ UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ DISPID *rgDispId)
- {
- HRESULT hr = S_OK;
- for (int i = 0; i < (int)cNames; i++)
- {
- CString cszName = rgszNames[i];
- if(cszName == L"myfunction")
- {
- bFind = TRUE;
- rgDispId[i] = 1;
- break;
- }
- else
- {
- // One or more are unknown so set the return code accordingly
- hr = ResultFromScode(DISP_E_UNKNOWNNAME);
- rgDispId[i] = DISPID_UNKNOWN;
- }
- }
- return hr;
- }
- STDMETHOD(Invoke)(
- /* [in] */ DISPID dispIdMember,
- /* [in] */ REFIID riid,
- /* [in] */ LCID lcid,
- /* [in] */ WORD wFlags,
- /* [out][in] */ DISPPARAMS *pDispParams,
- /* [out] */ VARIANT *pVarResult,
- /* [out] */ EXCEPINFO *pExcepInfo,
- /* [out] */ UINT *puArgErr)
- {
- if (!pDispParams)
- return E_INVALIDARG;
- if(wFlags & DISPATCH_METHOD)
- {
- int memberCount = sizeof(mapMember) / sizeof(MemberInfo);
- switch(dispIdMember)
- {
- case 1:
- {
- MessageBox(L"Hello JS!", L"");
- return S_OK;
- }
- break;
- default:
- return DISP_E_MEMBERNOTFOUND;
- break;
- }
- }
- return DISP_E_MEMBERNOTFOUND;
- }
- private:
- long m_dwRef;
- };
其次,实现一个IDocHostUIHandlerDispatch接口。其中最重要的是GetExternal,它返回一个CExtenalDispatch指针。
- class CBrowserHostUIHandlerImpl : public IDispatchImpl<IDocHostUIHandlerDispatch, &IID_IDocHostUIHandlerDispatch, &LIBID_ATLLib>
- {
- public:
- CBrowserHostUIHandlerImpl()
- {
- m_dwRef = 0;
- m_pDispatch = NULL;
- }
- ~CBrowserHostUIHandlerImpl()
- {
- if(m_pDispatch)
- {
- m_pDispatch->Release();
- m_pDispatch = NULL;
- }
- }
- STDMETHOD_(ULONG, AddRef)(){ return InterlockedIncrement(&m_dwRef); }
- STDMETHOD_(ULONG, Release)()
- {
- unsigned long l = InterlockedDecrement(&m_dwRef);
- if(l == 0)
- delete this;
- return l;
- }
- STDMETHOD(QueryInterface)(REFIID iid, LPVOID far* ppvObject)
- {
- HRESULT hrRet = S_OK;
- *ppvObject = NULL;
- if (IsEqualIID(iid, IID_IUnknown))
- *ppvObject = (IUnknown*)this;
- else if(IsEqualIID(iid, IID_IDispatch))
- *ppvObject = (IDispatch*)this;
- else if (IsEqualIID(iid, __uuidof(IDocHostUIHandler)))
- *ppvObject = (IDocHostUIHandler*)this;
- else
- hrRet = E_NOINTERFACE;
- if (S_OK == hrRet)
- ((IUnknown*)*ppvObject)->AddRef();
- return hrRet;
- }
- STDMETHOD(ShowContextMenu)(/* [in] */ DWORD dwID,
- /* [in] */ DWORD x,
- /* [in] */ DWORD y,
- /* [in] */ IUnknown *pcmdtReserved,
- /* [in] */ IDispatch *pdispReserved,
- /* [retval][out] */ HRESULT *dwRetVal)
- {
- *dwRetVal = S_OK;
- return S_OK;
- }
- STDMETHOD(GetHostInfo)(/* [out][in] */ DWORD *pdwFlags, /* [out][in] */ DWORD *pdwDoubleClick)
- {
- *pdwFlags = DOCHOSTUIFLAG_DIV_BLOCKDEFAULT | DOCHOSTUIFLAG_CODEPAGELINKEDFONTS | DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_SCROLL_NO | DOCHOSTUIFLAG_NO3DBORDER;
- *pdwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
- return S_OK;
- }
- STDMETHOD(ShowUI)(/* [in] */ DWORD dwID,
- /* [in] */ IUnknown *pActiveObject,
- /* [in] */ IUnknown *pCommandTarget,
- /* [in] */ IUnknown *pFrame,
- /* [in] */ IUnknown *pDoc,
- /* [retval][out] */ HRESULT *dwRetVal)
- {
- return S_OK;
- }
- STDMETHOD(HideUI)(){ return S_OK; }
- STDMETHOD(UpdateUI)(){ return S_OK; }
- STDMETHOD(EnableModeless)(/* [in] */ VARIANT_BOOL fEnable){ return S_OK; }
- STDMETHOD(OnDocWindowActivate)(/* [in] */ VARIANT_BOOL fActivate){ return S_OK; }
- STDMETHOD(OnFrameWindowActivate)(/* [in] */ VARIANT_BOOL fActivate){ return S_OK; }
- STDMETHOD(ResizeBorder)(/* [in] */ long left,
- /* [in] */ long top,
- /* [in] */ long right,
- /* [in] */ long bottom,
- /* [in] */ IUnknown *pUIWindow,
- /* [in] */ VARIANT_BOOL fFrameWindow)
- {
- return S_OK;
- }
- STDMETHOD(TranslateAccelerator)(/* [in] */ DWORD_PTR hWnd,
- /* [in] */ DWORD nMessage,
- /* [in] */ DWORD_PTR wParam,
- /* [in] */ DWORD_PTR lParam,
- /* [in] */ BSTR bstrGuidCmdGroup,
- /* [in] */ DWORD nCmdID,
- /* [retval][out] */ HRESULT *dwRetVal)
- {
- return S_FALSE;
- }
- STDMETHOD(GetOptionKeyPath)(/* [out] */ BSTR *pbstrKey, /* [in] */ DWORD dw){ return S_FALSE;}
- STDMETHOD(GetDropTarget)(/* [in] */ IUnknown *pDropTarget,/* [out] */ IUnknown **ppDropTarget){ return S_FALSE; }
- STDMETHOD(GetExternal)(/* [out] */ IDispatch **ppDispatch)
- {
- if(!m_pDispatch)
- {
- m_pDispatch = new CExtenalDispatch;
- }
- m_pDispatch->AddRef();
- *ppDispatch = m_pDispatch;
- return S_OK;
- }
- STDMETHOD(TranslateUrl)(/* [in] */ DWORD dwTranslate, /* [in] */ BSTR bstrURLIn, /* [out] */ BSTR *pbstrURLOut){ return S_FALSE; }
- STDMETHOD(FilterDataObject)(/* [in] */ IUnknown *pDO, /* [out] */ IUnknown **ppDORet){ return S_FALSE; }
- private:
- long m_dwRef;
- CExtenalDispatch * m_pDispatch;
- };
最后,在WebBrowser控制创建好后,调用SetExternalUIHandler。如下:
- CBrowserHostUIHandlerImpl * pHost = new CBrowserHostUIHandlerImpl;
- pHost->AddRef();
- SetExternalUIHandler(pHost);
- 从C调用JavaScript函数代码。
- 从C调用JavaScript函数代码。
- JavaScript 函数、函数调用
- Applet调用JavaScript函数
- JAVASCRIPT调用共通函数
- Applet调用JavaScript函数
- Applet调用JavaScript函数
- javascript中函数调用
- javascript 调用后台函数
- JavaScript调用C++函数
- javascript 调用 extjs 函数
- JavaScript函数调用规则
- javascript调用函数
- JavaScript函数调用方式
- java调用javascript函数
- javascript 函数调用笔记
- Applet调用JavaScript函数
- javascript函数调用笔记
- Linux内核Makefile模板,及其注意事项
- 基於jquery的驗證類庫(3)
- 初学c++
- Java中PreparedStatement和Statement的用法区别
- iOS7 UUID唯一标识
- JavaScript调用C++函数
- 基於jquery的驗證類庫(4) .
- C++异常处理
- 利用javax.mail写的一个简单发邮件的类
- 支持串口loadx命令下载
- 自定义Notification
- 左右值树常规操作的逻辑
- sparse coding理解
- camera前后置gpio口影响