See the question and my original answer on StackOverflow

The DispCallFunc function is declared like this:

HRESULT DispCallFunc(
  void       *pvInstance,
  ULONG_PTR  oVft,
  CALLCONV   cc,
  VARTYPE    vtReturn,
  UINT       cActuals,
  VARTYPE    *prgvt,
  VARIANTARG **prgpvarg,
  VARIANT    *pvargResult
);
  • pvInstance is a pointer [input]
  • oVft is a pointer [input]
  • cc is a 32-bit integer [input]
  • vtReturn is a 16-bit integer [input]
  • cActuals is a 32-bit integer [input]
  • prgvt is an array of 16-bit integers (so a pointer) [input]
  • prgpvarg is an array of pointer on VARIANTs (so a pointer) [input]
  • pvargResult is a pointer on a VARIANT, so a byref VBA's Variant [output]

So, for VBA:

Private Declare PtrSafe Function DispCallFunc Lib "OleAut32.dll" ( _
    ByVal pvInstance As LongPtr, _
    ByVal oVft As LongPtr, _
    ByVal cc As Long, _
    ByVal vtReturn As Integer, _
    ByVal cActuals As Long, _
    ByVal prgvt As LongPtr, _
    ByVal prgpvarg As LongPtr, _
    ByRef pvargResult As Variant) As Long