activex scripting 实现c++ 和 javascript交互

 首先activex scripting技术只适用于windows系统, 如果需要跨平台, 则放弃

#define SETERROR(hr) hr
#include <activscp.h>
class CScriptHost : public IActiveScriptSite
{
    // IActiveScriptSite
    STDMETHOD(GetItemInfo)(LPCOLESTR /*pstrName*/, DWORD /*dwReturnMask*/,
        IUnknown **ppiunkItem, ITypeInfo **ppti)
    {
        *ppiunkItem = NULL;
        *ppti = NULL;
        return S_OK;
    }

    STDMETHOD(OnScriptError)(IActiveScriptError *pscripterror)
    {
        return S_OK;
    }

    STDMETHOD(GetLCID)(LCID *plcid)
    {
        *plcid = NULL;
        return E_NOTIMPL;
    }

    STDMETHOD(GetDocVersionString)(BSTR* pbstrVersion)
    {
        *pbstrVersion = NULL;
        return E_NOTIMPL;
    }

    STDMETHOD(OnScriptTerminate)(const VARIANT * /*pvr*/, const EXCEPINFO * /*pei*/)
    {
        return S_OK;
    }

    STDMETHOD(OnStateChange)(SCRIPTSTATE /*ssScriptState*/)
    {
        return S_OK;
    }

    STDMETHOD(OnEnterScript)()
    {
        return S_OK;
    }

    STDMETHOD(OnLeaveScript)()
    {
        return S_OK;
    }
   
    HRESULT Init();
   
    HRESULT Close();
   
    HRESULT AddScriptFile(std::string const& file);
   
    HRESULT GetScriptDispatch(IDispatch** retval);

private:
 // Script Engine Wrapper Interfaces
 CComPtr<IActiveScript> m_pEngine;
 CComPtr<IActiveScriptParse> m_pEngineParse;
};

#include <atlbase.h>
#include <string>
#include <atlfile.h>

using namespace std;

HRESULT CScriptHost::Init(){
    CLSID clsJS;
    HRESULT hr = ::CLSIDFromProgID(L"javascript", &clsJS);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = ::CoCreateInstance(clsJS, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void**)&m_pEngine);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngine.QueryInterface(&m_pEngineParse);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngineParse->InitNew();
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngine->SetScriptSite(this);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngine->SetScriptState(SCRIPTSTATE_STARTED);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngine->SetScriptState(SCRIPTSTATE_CONNECTED);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    return S_OK;
}

HRESULT CScriptHost::Close()
{
    HRESULT hr = m_pEngine->SetScriptState(SCRIPTSTATE_DISCONNECTED);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    hr = m_pEngine->SetScriptState(SCRIPTSTATE_CLOSED);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }
    return S_OK;
}

HRESULT CScriptHost::AddScriptFile(string const& file)
{
    CAtlFile file;
    HRESULT hr = file.Create(file.c_str(), GENERIC_READ, 0, OPEN_EXISTING);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    ULONGLONG len;
    hr = file.GetSize(len);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    LARGE_INTEGER li;
    li.QuadPart = len;
    CAutoVectorPtr<char> szData(new char[li.LowPart+1]);
    if (!szData)
    {
        return SETERROR(E_OUTOFMEMORY);
    }

    DWORD dwBytesRead;
    hr = file.Read(szData, li.LowPart, dwBytesRead);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }

    szData[dwBytesRead] = '\0';
    file.Close();    USES_CONVERSION;
    wstring script = A2W(szData);    EXCEPINFO sEx;
    hr = m_pEngineParse->ParseScriptText(script.c_str(), NULL, NULL, NULL,
        1, 0, SCRIPTTEXT_ISVISIBLE | SCRIPTTEXT_ISPERSISTENT, NULL, &sEx);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }
    return S_OK;
}

HRESULT CScriptHost::GetScriptDispatch(IDispatch** retval)
{
    HRESULT hr = m_pEngine->GetScriptDispatch(NULL, retval);
    if (FAILED(hr))
    {
        return SETERROR(hr);
    }
    return S_OK;
}

使用说明:
假如有一个js文件, c:\test.js, 内容为
function add(x, y)
{
    return x + y;
}

c++代码中想去调用js 的add函数并且得到返回值的方法如下:
::CoInitialize(NULL);
CScriptHost host;
host.Init();
host.AddScriptFile("c:\\test.js");
CComPtr<IDispatch> pJs;
host.GetScriptDispatch(&pJs);
CComVariant var1(10);
CComVariant var2(20);
CComVariant ret;
pJs.Invoke2("add", &var1, &var2, &ret);
host.Close();
::CoUninitialize();
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值