{-
The primitive invokation mechanism. Exceptions are directed to the normal
@coFail@ function.
-}
primInvokeMethod :: DispAction 
                 -> Bool
                 -> DISPID
                 -> [VarIn] -> [VarIn]
                 -> IDispatch d 
                 -> IO (VARIANT)
primInvokeMethod action isfunction dispid argin argout iptr
      = let cargsout = fromIntegral (length argout)
            cargs    = cargsout + fromIntegral (length argin)
        in
           stackFrame (fromIntegral (sizeofVARIANT * fromIntegral cargs)) $ \ pargs ->
        do
           pargout      <- allocMemory (fromIntegral $ sizeofVARIANT * fromIntegral cargsout)
           let pargin   = pargs `addNCastPtr` (sizeofVARIANT * fromIntegral cargsout)

           writeSeqAtDec (fromIntegral sizeofVARIANT) argin  pargin
           writeSeqAtDec (fromIntegral sizeofVARIANT) argout pargout

           (pinfo,hr) <- dispatchInvoke (castIface iptr)
                              dispid lcidNeutral isfunction
                              action (fromIntegral cargs) 
                              cargsout
                              pargs pargout

           if (succeeded hr)
            then return pargout
            else if hr == dISP_E_EXCEPTION
                  then do 
                          pstr <- getExcepInfoMessage pinfo
                          str  <- unmarshallString (castPtr pstr)
                          coFree pstr
                          freeExcepInfo pinfo
                          freeMemory pinfo
                          freeMemVariants cargsout pargout
                          coFail str
                  else do 
                          putMessage "invoke failed"
                          freeMemVariants cargsout pargout
                          coFailHR hr

--Some helper functions for @Variants@.
primInvokeMethod :: DispAction 
                 -> Bool
                 -> DISPID
                 -> [VarIn] -> [VarIn]
                 -> IDispatch d 
                 -> IO (VARIANT)
primInvokeMethod action isfunction dispid argin argout iptr
      = let cargsout = fromIntegral (length argout)
            cargs    = cargsout + fromIntegral (length argin)
        in
           stackFrame (fromIntegral (sizeofVARIANT * fromIntegral cargs)) $ \ pargs ->
        do
           pargout      <- allocMemory (fromIntegral $ sizeofVARIANT * fromIntegral cargsout)
           let pargin   = pargs `addNCastPtr` (sizeofVARIANT * fromIntegral cargsout)

           writeSeqAtDec (fromIntegral sizeofVARIANT) argin  pargin
           writeSeqAtDec (fromIntegral sizeofVARIANT) argout pargout

           (pinfo,hr) <- dispatchInvoke (castIface iptr)
                              dispid lcidNeutral isfunction
                              action (fromIntegral cargs) 
                              cargsout
                              pargs pargout

           if (succeeded hr)
            then return pargout
            else if hr == dISP_E_EXCEPTION
                  then do 
                          pstr <- getExcepInfoMessage pinfo
                          str  <- unmarshallString (castPtr pstr)
                          coFree pstr
                          freeExcepInfo pinfo
                          freeMemory pinfo
                          freeMemVariants cargsout pargout
                          coFail str
                  else do 
                          putMessage "invoke failed"
                          freeMemVariants cargsout pargout
                          coFailHR hr

--Some helper functions for @Variants@.
primInvokeMethod action isfunction dispid argin argout iptr
      = let cargsout = fromIntegral (length argout)
            cargs    = cargsout + fromIntegral (length argin)
        in
           stackFrame (fromIntegral (sizeofVARIANT * fromIntegral cargs)) $ \ pargs ->
        do
           pargout      <- allocMemory (fromIntegral $ sizeofVARIANT * fromIntegral cargsout)
           let pargin   = pargs `addNCastPtr` (sizeofVARIANT * fromIntegral cargsout)

           writeSeqAtDec (fromIntegral sizeofVARIANT) argin  pargin
           writeSeqAtDec (fromIntegral sizeofVARIANT) argout pargout

           (pinfo,hr) <- dispatchInvoke (castIface iptr)
                              dispid lcidNeutral isfunction
                              action (fromIntegral cargs) 
                              cargsout
                              pargs pargout

           if (succeeded hr)
            then return pargout
            else if hr == dISP_E_EXCEPTION
                  then do 
                          pstr <- getExcepInfoMessage pinfo
                          str  <- unmarshallString (castPtr pstr)
                          coFree pstr
                          freeExcepInfo pinfo
                          freeMemory pinfo
                          freeMemVariants cargsout pargout
                          coFail str
                  else do 
                          putMessage "invoke failed"
                          freeMemVariants cargsout pargout
                          coFailHR hr

--Some helper functions for @Variants@.