Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Array Differentiation
#1
Is there anyway to differentiate between different array type?
Let's say I have 4 arrays with 4 different types:

Macro Macro132
Code:
Copy      Help
ARRAY(int) aInt.create(3)
aInt[0]=1
aInt[1]=2
aInt[2]=3

ARRAY(double) aDouble.create(3)
aDouble[0]=1.0
aDouble[1]=2.0
aDouble[2]=3.0

ARRAY(str) aStr="abc[]def[]ghi"

ARRAY(lpstr) aLpstr.create(3)
aLpstr[0]="abc"
aLpstr[1]="def"
aLpstr[2]="ghi"
How to differentiate between aInt, aDouble, aStr and aLpstr in coding not just by simply looking at their names?
#2
Get array type at run time? Some types can be extracted from SAFEARRAY structure. For other types can only get size of elements. I'll try to create a function for it if you need.
#3
Yes, could you post your function?
#4
What types will need to recognize?
int, double, str, lpstr - possible. What other types?
#5
But cannot get type of empty arrays.
#6
Right now I just need 2 types: int and str only.
Yes these arrays are not empty at all.
#7
Function GetArrayType
Code:
Copy      Help
;/
function# SAFEARRAY*a ;;Returns: str 256, lpstr 257, Acc 258, int VT_I4, byte VT_UI1, word VT_I2, long VT_I8, double VT_R8, other VT_, unknown -size, empty 0.

;Returns array type, if possible.
;If cannot get type, returns -size.
;Returns 0 if array not created or somehow invalid.

;For some types returns one of VT_ constants. Some listed above.
;For some other types returns >=256. See above. You can edit this function to add more known types.
;For COM interfaces returns either VT_UNKNOWN or VT_DISPATCH.
;For pointers returns VT_I4 (int).


word vt; IRecordInfo ri
if !SafeArrayGetVartype(a &vt)
,if(vt>255) ret iif(vt&0xff00=VT_BYREF VT_I4 0)
,if(vt!=VT_RECORD) ret vt
,if !SafeArrayGetRecordInfo(a &ri)
,,ARRAY(int)+ ___gat; int i
,,if !___gat.len
,,,lock
,,,if !___gat.len
,,,,ARRAY(str) a0.create
,,,,ARRAY(lpstr) a1.create
,,,,ARRAY(Acc) a2.create
,,,,;Here you can add more array types like the above 3 lines. Then restart QM or reopen file.
,,,,;Add only composite types, because simple types like RECT don't have IRecordInfo. Simple types have only size.
,,,,;Composite types are types and classes that have a destructor or contain str, BSTR, VARIANT, ARRAY, interface, another composite type.
,,,,
,,,,SAFEARRAY** k=&a0.psa
,,,,___gat.create(&k-&a0/4)
,,,,for(i 0 ___gat.len) SafeArrayGetRecordInfo(k[i] +&___gat[i])
,,
,,for(i 0 ___gat.len) if(ri=___gat[i]) ret 256+i

ret -SafeArrayGetElemsize(a)

test
Macro Macro2422
Code:
Copy      Help
out
ARRAY(int) aInt.create
ARRAY(byte) aByte.create
ARRAY(word) aWord.create
ARRAY(long) aLong.create
ARRAY(double) aDouble.create
ARRAY(str) aStr.create
ARRAY(lpstr) aLpstr.create
ARRAY(BSTR) aBstr.create
ARRAY(VARIANT) aVariant.create
ARRAY(CURRENCY) aCurrency.create
ARRAY(FLOAT) aFloat.create
ARRAY(DECIMAL) aDecimal.create
ARRAY(DATE) aDate.create
ARRAY(RECT) aRect.create
ARRAY(Acc) aAcc.create
ARRAY(SmtpMail) aSmtpMail.create
ARRAY(IXml) aIXml.create
ARRAY(IAccessible) aIAccessible.create
ARRAY(double*) aPtr.create
ARRAY(int) aNotCreated

int t=GetArrayType(aInt)
if(t=0) out "array not created or invalid"
else if(t<0) out "type unknown, size=%i" -t
else
,sel t
,,case VT_I4; out "int or pointer"
,,case VT_UI1 out "byte"
,,case VT_I2 out "word"
,,case VT_I8 out "long"
,,case VT_R8 out "double"
,,case VT_BSTR out "BSTR"
,,case VT_VARIANT out "VARIANT"
,,case VT_CY out "CURRENCY"
,,case VT_R4 out "FLOAT"
,,case VT_DECIMAL out "DECIMAL"
,,case VT_DATE out "DATE"
,,case VT_UNKNOWN out "IUnknown or an interface that does not have IDispatch"
,,case VT_DISPATCH out "IDispatch or an interface that has IDispatch"
,,case 256 out "str"
,,case 257 out "lpstr"
,,case 258 out "Acc"
#8
You give me more than what I've asked for! Big Grin
I really appreciate your fast response and great effort for this.
Thank you very much as always, Gintaras!
#9
I need to get the type of the array variable passed in. Is this possible? Alternatively, are there any other solutions?
The following code will show an error

Macro Macro29
Code:
Copy      Help
ARRAY(str) as; out sub.f(as)
ARRAY(str) ai; out sub.f(ai)

#sub f
function~ `arg

sel GetArrayType(arg)
,case VT_I4; ret "int[]"
,case 256; ret "string[]"
#10
Macro Macro29
Code:
Copy      Help
ARRAY(str) as.create; out sub.f(as)
ARRAY(int) ai.create; out sub.f(ai)

#sub f
function~ SAFEARRAY*arg

sel GetArrayType(arg)
,case VT_I4; ret "int[91]]"
,case 256; ret "string[91]]"
#11
Thanks for your help.


Forum Jump:


Users browsing this thread: 1 Guest(s)