• C++代码中回调JS方法


    前段时间开发了一个COM组件配合web前端使用,遇到了C++中调用JS代码的问题,在网上查了很多资料,现总结一下,留作以后察看。

    C++中调用JS代码主要有两种情况:1. IE线程中调用;2. 其他线程调用

    1. IE线程中调用:这种情况网上已经有很多资料,下面列出示列代码:

    C++代码

    STDMETHODIMP CJsInvoker::InvokeJsFunc(LONG para1, LONG para2, VARIANT jsFunction, LONG* retValue)
    {
        CComPtr<IDispatch> 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>(DISPID_VALUE), arg, 2, &pvarRet);
    
        *retValue = pvarRet.lVal;
    
        return S_OK;
    }

     JS代码 

      <script type="text/javascript">
          // 两个参数的回调方法
          function jsCallbackFunc(a, b)
          {
            return a + b;
          }
     
          var obj = new ActiveXObject("ComCallJsFunction.JsInvoker");
          var retValue = objA.InvokeJsFunc(1, 2, jsCallbackFunc);
          alert(retValue); // 返回值为3
      </script>

    从代码中可以看出,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<IDispatch> 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>(DISPID_VALUE), arg, 2, &pvarRet);
        ::CoUninitialize();
        return S_OK;
    }

     JS代码

      <script type="text/javascript">
          // 两个参数的回调方法
          function jsCallbackFunc(a, b)
          {
            return a + b;
          }
     
          var obj = new ActiveXObject("ComCallJsFunction.JsInvoker");
          var retValue = objA.InvokeJsFunc(1, 2, jsCallbackFunc);
          alert(retValue); // 此时返回值没有意义
      </script>
  • 相关阅读:
    shell查看内存
    shell 终端字符颜色
    PHP获取一年有几周以及每周开始日期和结束日期
    PHP 计算当前时间是这一年的第几周
    laravel orWhere
    进程与线程的一个简单解释
    go cap和len的区别
    go 总结常用函数
    go append 函数常见操作
    php 字符串常用函数
  • 原文地址:https://www.cnblogs.com/wadexia/p/COM-JS.html
Copyright © 2020-2023  润新知