IE的window.external调用宿主程序函数时整数类型问题

在项目中使使用window.external.foobar(intVal)调用c++程序中webbrowser提供的函数。在web控件的Invoke方法中,获取该参数intVal。

HRESULT __stdcall XXXWebBrowser::Invoke( 
          DISPID  dispIdMember,
          REFIID  riid,              
          LCID  lcid,                
          WORD  wFlags,              
          DISPPARAMS FAR*  pDispParams,  
          VARIANT FAR*  pVarResult,  
          EXCEPINFO FAR*  pExcepInfo,  
          unsigned int FAR*  puArgErr  
          ){
      int v = pDispParams->rgvarg[0].intVal;
}

pDispParams->rgvarg[0]是一个VARIANT,类型为VT_I4。以前一直直接使用intVal来取整数值,都很正常。但在当intVal为UNIX时间戳时,发现该参数在c++中变成了VT_R8,变成了浮点数。

觉得奇怪,时间戳明明还在整数的范围内,为什么会变成了浮点数。
于是在js里写了一些测试代码,最后发现临界值为 0x40000000,超过此值的调用后VARIANT类型为VT_R8,不超过时,为VT_I4。

于是代码做了下兼容:

uint32_t  XXXWebBrowser::GetDispUIntArg( DISPPARAMS* pDispParams, uint32_t index, uint32_t defaultValue /*= 0*/ )
{
    if (index >= pDispParams->cArgs)
    {
        assert(false);
        return defaultValue;
    }

       switch (pDispParams->rgvarg[argIndex].vt)
    {
    case VT_I2:
    case VT_UI2:
    case VT_I4:
    case VT_UI4:
    case VT_I8:
    case VT_UI8:
        {
            return pDispParams->rgvarg[argIndex].intVal;
        }
        break;
    case VT_R4:
    case VT_R8:
        {
            return (uint32_t)pDispParams->rgvarg[argIndex].dblVal;
        }
        break;
    default:
        GAMEMGR_ASSERT(false && "GetDispUIntArg接收到了不支持的类型");
               return defaultValue;
    }

你可能感兴趣的:(IE的window.external调用宿主程序函数时整数类型问题)