Преобразование 32-битного вызова OleAut в 64-битный в VBA - PullRequest
1 голос
/ 13 апреля 2020

У меня возникли некоторые проблемы с преобразованием этого вызова API в 64-разрядный доступный вызов из VBA.

Объявление API

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

Код клиента

Public Sub Main()

    ' On this line I get "compile error: type mismatch" because AddressOf method
    ' returns LongPtr but DispCallFunc expects Long.
    DispCallFunc 0, AddressOf Foo, CLng(4), VbVarType.vbEmpty, 0, 0, 0, 0

End Sub


Private Sub Foo()
    Debug.Print 100
End Sub

Я пытался изменить Long на LongPtr в DispCallFunc, но каждый раз, когда я делаю это изменение в API и запускаю макрос, Excel зависает.

1 Ответ

1 голос
/ 13 апреля 2020

Функция DispCallFun c объявлена ​​так:

HRESULT DispCallFunc(
  void       *pvInstance,
  ULONG_PTR  oVft,
  CALLCONV   cc,
  VARTYPE    vtReturn,
  UINT       cActuals,
  VARTYPE    *prgvt,
  VARIANTARG **prgpvarg,
  VARIANT    *pvargResult
);
  • pvInstance - указатель [input]
  • oVft - указатель [ input]
  • cc - 32-разрядное целое число [input]
  • vtReturn - 16-разрядное целое число [input]
  • cActuals - 32-разрядное целое число [ input]
  • prgvt - это массив 16-битных целых чисел (с указателем) [input]
  • prgpvarg - это массив указателей на VARIANT (с указателем) [input]
  • pvargResult - указатель на VARIANT, поэтому вариант VBA byref VBA [output]

Итак, для 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
...