1 (изменено: serzh82saratov, 2017-02-07 04:42:26)

Тема: AHK: Передача массива как типа данных VARIANT

Пытаюсь методу сом объекта передать массив в типе данных VARIANT:

arr := ComObjArray(VT_VARIANT := 12, 1)
arr[0] := 62
ComObj.Method(arr)

Который ему требуется, судя по коду VBA.

Dim gpCode(0) As Integer 
gpCode(0) = 62
Dim groupCode As Variant
groupCode = gpCode
' указываю groupCode как передаваемый параметр

Может вообще не туда копаю?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

2 (изменено: serzh82saratov, 2017-02-07 04:42:19)

Re: AHK: Передача массива как типа данных VARIANT

В справке такой пример нашёл, тоже не получается.


arr := ComVar()
arr[0] := 62 
ComObj.Method(arr)



; ComVar: Creates an object which can be used to pass a value ByRef.
;   ComVar[] retrieves the value.
;   ComVar[] := Val sets the value.
;   ComVar.ref retrieves a ByRef object for passing to a COM function.
ComVar(Type=0xC)
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; Create an array of 1 VARIANT.  This method allows built-in code to take
    ; care of all conversions between VARIANT and AutoHotkey internal types.
    arr := ComObjArray(Type, 1)
    ; Lock the array and retrieve a pointer to the VARIANT.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; Store the array and an object which can be used to pass the VARIANT ByRef.
    return { ref: ComObject(0x4000|Type, arr_data), _: arr, base: base }
}

ComVarGet(cv, p*) { ; Called when script accesses an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]
        return cv._[0]
}

ComVarSet(cv, v, p*) { ; Called when script sets an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]:=v
        return cv._[0] := v
}

ComVarDel(cv) { ; Called when the object is being freed.
    ; This must be done to allow the internal array to be freed.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3

Re: AHK: Передача массива как типа данных VARIANT

Опечатка:

ComObj.Method(arr.ref)

4

Re: AHK: Передача массива как типа данных VARIANT

Так тоже пробовал, но это вроде аналог byref.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Передача массива как типа данных VARIANT

Проверил на своём объекте код из первого поста — методу передаётся тип VT_ARRAY | VT_VARIANT. Т.е. массив вариантов. Может, вашему объекту надо массив целых чисел? Т.е. VT_ARRAY | VT_I4, например. Сам массив, конечно, в варианте передаётся, но его члены, возможно, в варианты упаковывать не надо.

Код из второго поста передаёт тип VT_DISPATCH, т.е. объект.

Код от Malcev'a — ссылку на пустой вариант.

6 (изменено: YMP, 2017-02-07 16:33:11)

Re: AHK: Передача массива как типа данных VARIANT

Вот так передаётся массив 32-битных целых:


arr := ComObjArray(VT_I4 := 3, 1)
arr[0] := 62
ComObj.Method(arr)

7

Re: AHK: Передача массива как типа данных VARIANT

Ругается всё равно.

Error:  0x80070057 - Параметр задан неверно.
Source: AutoCAD
Description: Недопустимый аргумент FilterType в Select

Не пойму из справки (параметр FilterType) что ему надо.

VBA программист пишет:

В таком виде 62 и 3 задавать нельзя. Это же массивы "завернутые" в Variant, а не просто целые числа.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

8

Re: AHK: Передача массива как типа данных VARIANT

Массив будет завёрнут в Вариант при передаче методу, АНК сам это сделает. А члены массива заворачивать не надо, судя по этому:


Dim gpCode(0) As Integer
Dim dataValue(0) As Variant

Если члены тоже Варианты, то это объявляется явным образом. Значит, они просто целые числа. Но Integer в VBA, как я нагулил, это 16-битные числа, а не 32-битные. Так что, наверно, надо так:


arr := ComObjArray(VT_I2 := 2, 1)
arr[0] := 62
ComObj.Method(arr)

9

Re: AHK: Передача массива как типа данных VARIANT

YMP
Спасибо огромное, работает!

Следующий параметр FilterData почему то надо передавать как VT_VARIANT := 12, не подскажете почему так, ведь в справке тип такой же указан. VBA это непонятно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

10

Re: AHK: Передача массива как типа данных VARIANT

Сами массивы передаются оба в Вариантах, но у gpCode члены имеют тип Integer, а у dataValue они тоже Варианты. Возможно, в этом массиве нужна возможность передавать разные типы, поэтому члены массива и обернули в Варианты. Т.е. формально все элементы массива имеют один тип, Вариант, один размер, как и положено. Но внутри Вариантов уже могут быть данные разных типов и размеров. Для этого, наверно, тип Вариант и был когда-то выдуман.

11

Re: AHK: Передача массива как типа данных VARIANT

Спасибо, после АНК конечно все эти типы кажутся чем то лишним. Это вообще нужно только для повышения производительности?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

Re: AHK: Передача массива как типа данных VARIANT

Скорее, чтобы компиляторы могли отлавливать ошибки программистов.