Thanks for your time, and your clarifications. Back to my original question, I think know what the API wants (because it's stated in the documentation and because it works in VBA): an array of long (or string, boolean, whatever) passed by reference.
I did see your test build, which is why I finally posted this question, but I didn't find any documentation for ComObject, so my tests with it didn't work. I was definitely ignorant that 'For types with the VT_BYREF flag, you need to pass the address of a buffer, not the value itself.' So to follow your suggestion:
Code: Select all
; Create a 4bype variable named r4
VarSetCapacity(r4, 4, 0)
; Get a reference to this variable with a type of VT_BYREF|VT_R4
ref := ComObject(0x4004, &r4)
; Assign an initial value to the variable
; This is the bonus feature that only works in the test build
ref[] := initial_value
I don't see any use of arrays here. Am I missing something? My problem is with passing arrays, not variables byref. I have successfully used things such as VT_BYREF|VT_BOOL in AHK.
; First I test with a function that expects a non-array boolean by reference. Here "738" is the name of a PointObj that may or may not be selected. The API function does not expect an initial value, so I commented it out:
Code: Select all
VarSetCapacity(selc, 4, 0), selcRef := ComObject(0x400B, &selc) ;, selcRef[] := initial_value
SapModel.PointObj.GetSelected("738", selcRef)
msgbox % -selcRef[]
; This works as expected.
; Then I test with a function that expects arrays:
Code: Select all
VarSetCapacity(NumberItems, 4, 0), NumberItemsRef := ComObject(0x4004, &NumberItems) ;, NumberItemsRef[] := initial_value
VarSetCapacity(ObjectType, 4, 0), ObjectTypeRef := ComObject(0x4004, &ObjectType) ;, ObjectTypeRef[] := initial_value
VarSetCapacity(ObjectName, 4, 0), ObjectNameRef := ComObject(0x4008, &ObjectName) ;, ObjectNameRef[] := initial_value
SapModel.SelectObj.GetSelected(NumberItemsRef, ObjectTypeRef, ObjectNameRef)
NumberItemsValue := NumberItemsRef[]
ObjectTypeValue := ObjectTypeRef[]
ObjectNameValue := ObjectNameRef[]
msgbox % NumberItemsValue
for k, v in ObjectTypeValue
msgbox %k%, %v%
; This does not work.
; This is what I originally had working (the only code in this post not requiring your test build):
Code: Select all
arr := ComObjArray(0xB, 1)
DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
ref := ComObjParameter(0x4000|0xB, arr_data)
SapModel.PointObj.GetSelected("738", ref)
Msgbox % -arr[0]
; Interestingly, your suggestion also works without VarSetCapacity:
Code: Select all
selcRef := ComObject(0x400B, &selc) ;, selcRef[] := initial_value
SapModel.PointObj.GetSelected("738", selcRef)
msgbox % -selcRef[]
; Maybe if I set it to an array instead of a variable?
Code: Select all
selc := ComObjArray(0xB, 1), selcRef := ComObject(0x400B, &selc) ;, selcRef[] := initial_value
SapModel.PointObj.GetSelected("738", selcRef)
msgbox % -selcRef[]
; That worked as well. Back to the array API function:
Code: Select all
NumberItems := "", NumberItemsRef := ComObject(0x4004, &NumberItems) ;, NumberItemsRef[] := initial_value
ObjectType := ComObjArray(0x4, 1), ObjectTypeRef := ComObject(0x4004, &ObjectType) ;, ObjectTypeRef[] := initial_value
ObjectName := ComObjArray(0x8, 1), ObjectNameRef := ComObject(0x4008, &ObjectName) ;, ObjectNameRef[] := initial_value
msgbox ok
SapModel.SelectObj.GetSelected(NumberItemsRef, ObjectTypeRef, ObjectNameRef)
msgbox crashes ahk before getting here
NumberItemsValue := NumberItemsRef[]
ObjectTypeValue := ObjectTypeRef[]
ObjectNameValue := ObjectNameRef[]
msgbox % NumberItemsValue
for k, v in ObjectTypeValue
msgbox %k%, %v%
I tried a couple variations on the parameters is this last setup and they all crashed AHK.