-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#9] continue intelligent param handling
* put it into a new function * make it work more generic * retrieve FUNCDESC, ELEMDESC & TYPEDESC for param in ITL_InterfaceWrapper.__Set(), too * call the new function from both and __Set()
- Loading branch information
maul.esel
committed
Apr 3, 2012
1 parent
faf4db8
commit fc2ae59
Showing
4 changed files
with
136 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
ITL_ParamToVARIANT(info, tdesc, value, byRef variant, index) | ||
{ | ||
static VT_PTR := 26, VT_USERDEFINED := 29, VT_VOID := 24, VT_BYREF := 0x4000, VT_RECORD := 36, VT_UNKNOWN := 13 | ||
, sizeof_VARIANT := 8 + 2 * A_PtrSize | ||
, TYPEKIND_RECORD := 1, TYPEKIND_INTERFACE := 3 | ||
local hr, vt := NumGet(1*tdesc, A_PtrSize, "UShort"), converted := false, indirectionLevel := 0 | ||
, refHandle, refInfo := 0, refAttr := 0, refKind | ||
|
||
VarSetCapacity(variant, sizeof_VARIANT, 00) ; init variant | ||
while (vt == VT_PTR) | ||
{ | ||
tdesc := NumGet(1*tdesc, 00, "Ptr") ; TYPEDESC::lptdesc | ||
, vt := NumGet(1*tdesc, A_PtrSize, "UShort") ; TYPEDESC::vt | ||
, indirectionLevel++ | ||
} | ||
|
||
if (vt == VT_USERDEFINED && IsObject(value) && !ITL_IsComObject(value)) ; a struct or interface wrapper was passed | ||
{ | ||
NumPut(value[ITL.Properties.INSTANCE_POINTER], variant, 08, "Ptr") ; put instance pointer into VARIANT | ||
|
||
; get the type kind of the given wrapper: | ||
; ============================================= | ||
refHandle := NumGet(1*tdesc, 00, "UInt") ; TYPEDESC::hreftype | ||
hr := DllCall(NumGet(NumGet(info+0), 14*A_PtrSize, "Ptr"), "Ptr", info, "UInt", refHandle, "Ptr*", refInfo, "Int") ; ITypeInfo::GetRefTypeInfo() | ||
if (ITL_FAILED(hr) || !refInfo) | ||
{ | ||
throw Exception(ITL_FormatException("Failed to convert parameter #" index "." | ||
, "ITypeInfo::GetRefTypeInfo() (handle: " refHandle ") failed." | ||
, ErrorLevel, hr | ||
, !refInfo, "Invalid ITypeInfo pointer: " refInfo)*) | ||
} | ||
hr := DllCall(NumGet(NumGet(refInfo+0), 03*A_PtrSize, "Ptr"), "Ptr", refInfo, "Ptr*", refAttr, "Int") ; ITypeInfo::GetTypeAttr() | ||
if (ITL_FAILED(hr) || !refAttr) | ||
{ | ||
throw Exception(ITL_FormatException("Failed to convert parameter #" index "." | ||
, "ITypeInfo::GetTypeAttr() failed." | ||
, ErrorLevel, hr | ||
, !refAttr, "Invalid TYPEATTR pointer: " refAttr)*) | ||
} | ||
refKind := NumGet(1*refAttr, 36+A_PtrSize, "UInt") | ||
; ============================================= | ||
|
||
if (refKind == TYPEKIND_RECORD) | ||
{ | ||
; if (indirectionLevel > 0) | ||
; ... | ||
NumPut(VT_RECORD, variant, 00, "UShort") | ||
, NumPut(value.base[ITL.Properties.TYPE_RECORDINFO], variant, 08 + A_PtrSize, "Ptr") | ||
} | ||
else if (refKind == TYPEKIND_INTERFACE) | ||
{ | ||
if (indirectionLevel < 1) | ||
{ | ||
throw Exception(ITL_FormatException("Failed to convert parameter #" index "." | ||
, "Interfaces cannot be passed by value." | ||
, ErrorLevel, "" | ||
, indirectionLevel < 1, "Invalid indirection level: " indirectionLevel)*) | ||
} | ||
NumPut(VT_UNKNOWN, variant, 00, "UShort") | ||
} | ||
else | ||
{ | ||
ObjRelease(refInfo) ; cleanup | ||
throw Exception(ITL_FormatException("Failed to convert parameter #" index "." | ||
, "Cannot handle other wrappers than interfaces and structures." | ||
, ErrorLevel, "")*) | ||
} | ||
ObjRelease(refInfo), refInfo := 0, refAttr := 0 ; cleanup | ||
converted := true | ||
} | ||
else if (!IsObject(value) && vt == VT_VOID && indirectionLevel == 1) | ||
{ | ||
value := ComObjParameter(VT_BYREF, value) | ||
} | ||
; todo: handle arrays (native and safe) | ||
|
||
if (!converted) | ||
ITL_VARIANT_Create(value, variant) ; create VARIANT | ||
|
||
; handle: VT_CARRAY, VT_I8, VT_LPSTR, VT_LPWSTR, VT_SAFEARRAY, VT_PTR, VT_UI8, ... | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters