C++和js相互调用是个有意思的事情。
一、js中调用C++函数。函数原型
int g_FunSub(int x,int y);
调用方式如下:
<html>具体实现是在C++代码中写的:
<head>
<meta charset="utf-8" />
<title></title>
<script language="javascript">
function CallCppFunSub(x,y)
{
var num = window.external.g_FunSub(x,y);
alert(num);
return num
}
function JsFunSub(x,y)
{
var num = x - y;
alert(num);
return num
}
</script>
</head>
<body>
<button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>
</body>
</html>
#pragma once
class CWebBrowserExUI :
public CWebBrowserUI
{
public:
CWebBrowserExUI();
~CWebBrowserExUI();
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(__RPC__in REFIID riid, __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, UINT cNames, LCID lcid, __RPC__out_ecount_full(cNames) DISPID *rgDispId);
virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)
{
//重写GetExternal返回一个ClientCall对象
*ppDispatch = this;
return S_OK;
}
};
#include "stdafx.h"
#include "WebBrowserExUI.h"
#include <atlcomcli.h>
int g_FunSub(int x, int y)
{
return (x - y);
}
CWebBrowserExUI::CWebBrowserExUI()
{
}
CWebBrowserExUI::~CWebBrowserExUI()
{
}
LPCTSTR CWebBrowserExUI::GetClass() const
{
return _T("WebBrowserExUI");
}
LPVOID CWebBrowserExUI::GetInterface(LPCTSTR pstrName)
{
if (_tcsicmp(pstrName, _T("WebBrowserEx")) == 0)
return static_cast<CWebBrowserExUI*>(this);
return CActiveXUI::GetInterface(pstrName);
}
HRESULT CWebBrowserExUI::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
//DISP ID 从200开始
if (_tcscmp(rgszNames[0], _T("g_FunSub")) == 0)
*rgDispId = 500;
return S_OK;
}
HRESULT CWebBrowserExUI::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
//MyOutputDebugStringW(L"%d\n", dispIdMember);
switch (dispIdMember)
{
case 500:
{
// 注意参数顺序,反向
VARIANTARG *varArg = pDispParams->rgvarg;
int x = _ttoi(static_cast<_bstr_t>(varArg[1]));
int y = _ttoi(static_cast<_bstr_t>(varArg[0]));
int n = g_FunSub(x, y);
*pVarResult = CComVariant(n);
return S_OK;
}
default:
break;
}
return CWebBrowserUI::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}
function JsFunSub(x,y)C++中这么调用:
void CMainFrameWnd::OnClick(TNotifyUI& msg)
{
CDuiString sCtrlName = msg.pSender->GetName();
if (sCtrlName.CompareNoCase(_T("CallJsBtn")) == 0)
{
// C++调用js方法,示例
// 注意参数顺序,反向
VARIANT arg[2] = { CComVariant(7),CComVariant(3)};//JsFunSub(3,7)
VARIANT varRet;
m_pBrowser->InvokeMethod(m_pBrowser->GetHtmlWindow(),_T("JsFunSub"),&varRet,arg,2);
int nResult = varRet.intVal;//-4
return;
}
WindowImplBase::OnClick(msg);
}
js中这样实现:
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script language="javascript">
function CallCppFunSub(x,y)
{
var num = window.external.g_FunSub(x,y);
alert(num);
return num
}
function JsFunSub(x,y)
{
var num = x - y;
alert(num);
return num
}
</script>
</head>
<body>
<button type="button" onclick="CallCppFunSub(4,7)">调用C++函数</button>
</body>
</html>
C++调用javascript请移步这里: http://blog.csdn.net/sunflover454/article/details/60570940
示例工程下载地址(VS2013):