程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++中調用JS代碼的問題

C++中調用JS代碼的問題

編輯:關於C++

前段時間開發了一個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>
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved