Sorry to say, to my knowledge QB64 does not directly support that. However I have had a similar issue and have a couple of work arounds.
Two methods I have are to use STRINGS or to use _MEM's. They both have their pro and cons.
String method is the simpliest.
Code: (Select All)
| |
| |
| |
| |
| TYPE tUDT |
| longArray AS STRING * 1028 |
| END TYPE |
| |
| DIM udt AS tUDT |
| DIM iter AS LONG |
| |
| FOR iter = 1 TO 256 |
| SetArrayLong udt.longArray, iter, iter * 2000000 |
| PRINT iter; ": "; getArrayLong(udt.longArray, iter) |
| NEXT |
| |
| FUNCTION getArrayLong& (s AS STRING, p AS LONG) |
| IF p > 0 AND p * 4 + 4 <= LEN(s) THEN getArrayLong = CVL(MID$(s, p * 4, 4)) |
| END FUNCTION |
| |
| SUB SetArrayLong (s AS STRING, p AS LONG, v AS LONG) |
| IF p > 0 AND p * 4 + 4 <= LEN(s) THEN MID$(s, p * 4) = MKL$(v) |
| END SUB |
| |
| FUNCTION getArraySingle! (s AS STRING, p AS LONG) |
| IF p > 0 AND p * 4 + 4 <= LEN(s) THEN getArraySingle = CVS(MID$(s, p * 4, 4)) |
| END FUNCTION |
| |
| SUB SetArraySingle (s AS STRING, p AS LONG, v AS SINGLE) |
| IF p > 0 AND p * 4 + 4 <= LEN(s) THEN MID$(s, p * 4) = MKS$(v) |
| END SUB |
| |
| FUNCTION getArrayInteger% (s AS STRING, p AS LONG) |
| IF p > 0 AND p * 2 + 2 <= LEN(s) THEN getArrayInteger = CVI(MID$(s, p * 2, 2)) |
| END FUNCTION |
| |
| SUB SetArrayInteger (s AS STRING, p AS LONG, v AS INTEGER) |
| IF p > 0 AND p * 2 + 2 <= LEN(s) THEN MID$(s, p * 2) = MKI$(v) |
| END SUB |
| |
| FUNCTION getArrayDouble# (s AS STRING, p AS LONG) |
| IF p > 0 AND p * 8 + 8 <= LEN(s) THEN getArrayDouble = CVL(MID$(s, p * 8, 8)) |
| END FUNCTION |
| |
| SUB SetArrayDouble (s AS STRING, p AS LONG, v AS DOUBLE) |
| IF p > 0 AND p * 8 + 8 <= LEN(s) THEN MID$(s, p * 8) = MKD$(v) |
| END SUB |
The demo above uses longs which is 4 bytes. Integers in QB64 are 2 bytes.
The _MEM method is a bit more complicated.
Code: (Select All)
| |
| SCREEN 12: _FONT 8 |
| _TITLE "UDT_ARRAYS.bas" |
| DIM AS LONG i |
| DIM AS DOUBLE v |
| CONST cMAXELEMENTS = 10 |
| |
| |
| CONST cDT_BYTE = 1 |
| CONST cDT_INTEGER = 2 |
| CONST cDT_LONG = 4 |
| CONST cDT_SINGLE = 4 |
| CONST cDT_DOUBLE = 8 |
| CONST cDT_INTEGER64 = 8 |
| CONST cDT_FLOAT = 32 |
| |
| TYPE tARRAYS |
| UDT_Array0 AS _MEM |
| UDT_Array1 AS _MEM |
| UDT_Array2 AS _MEM |
| END TYPE |
| |
| DIM AS tARRAYS UDT |
| |
| |
| createUDTArray UDT.UDT_Array0, cDT_DOUBLE, cMAXELEMENTS |
| createUDTArray UDT.UDT_Array1, cDT_SINGLE, cMAXELEMENTS |
| createUDTArray UDT.UDT_Array2, cDT_INTEGER, cMAXELEMENTS |
| PRINT "ARRAY Doubles ARRAY Singles ARRAY Integers" |
| |
| PRINT "Create initial Values, Store them, and retrieve" |
| FOR i = 0 TO cMAXELEMENTS |
| v = INT(RND * 5 * 100) / 100 |
| setElementDBL UDT.UDT_Array0, i, v |
| PRINT USING "index: ##-> #.## "; i; getElementDBL(UDT.UDT_Array0, i); |
| v = INT(RND * 5 * 100) / 100 |
| setElementSIGL UDT.UDT_Array1, i, v |
| PRINT USING "index: ##-> #.## "; i; getElementSIGL(UDT.UDT_Array1, i); |
| v = INT(RND * 5) |
| setElementINT UDT.UDT_Array2, i, v |
| PRINT USING "index: ##-> #.##"; i; getElementINT(UDT.UDT_Array2, i) |
| NEXT |
| |
| |
| resizeUDTArray UDT.UDT_Array0, cDT_DOUBLE, cMAXELEMENTS * 2 |
| resizeUDTArray UDT.UDT_Array1, cDT_SINGLE, cMAXELEMENTS * 2 |
| resizeUDTArray UDT.UDT_Array2, cDT_INTEGER, cMAXELEMENTS * 2 |
| |
| |
| PRINT "Double the size of the array" |
| FOR i = 0 TO cMAXELEMENTS * 2 |
| PRINT USING "index: ##-> #.## "; i; getElementDBL(UDT.UDT_Array0, i); |
| PRINT USING "index: ##-> #.## "; i; getElementSIGL(UDT.UDT_Array1, i); |
| PRINT USING "index: ##-> #.##"; i; getElementINT(UDT.UDT_Array2, i) |
| NEXT |
| |
| |
| resizeUDTArray UDT.UDT_Array0, cDT_DOUBLE, cMAXELEMENTS / 2 |
| resizeUDTArray UDT.UDT_Array1, cDT_SINGLE, cMAXELEMENTS / 2 |
| resizeUDTArray UDT.UDT_Array2, cDT_INTEGER, cMAXELEMENTS / 2 |
| |
| |
| PRINT "Half the size of the array" |
| FOR i = 0 TO cMAXELEMENTS / 2 |
| PRINT USING "index: ##-> #.## "; i; getElementDBL(UDT.UDT_Array0, i); |
| PRINT USING "index: ##-> #.## "; i; getElementSIGL(UDT.UDT_Array1, i); |
| PRINT USING "index: ##-> #.##"; i; getElementINT(UDT.UDT_Array2, i) |
| NEXT |
| |
| |
| SUB createUDTArray (o AS _MEM, dt AS LONG, size AS LONG) |
| |
| o = _MEMNEW((size + 1) * dt) |
| END SUB |
| |
| SUB resizeUDTArray (o AS _MEM, dt AS LONG, size AS LONG) |
| DIM AS _MEM old |
| DIM AS LONG iter |
| |
| old = o |
| |
| createUDTArray o, dt, size |
| |
| iter = 0: DO WHILE iter < o.SIZE |
| _MEMPUT o, o.OFFSET + iter, 0 AS _BYTE |
| iter = iter + 1: LOOP |
| |
| iter = 0: DO WHILE iter < o.SIZE AND iter < old.SIZE |
| _MEMPUT o, o.OFFSET + iter, _MEMGET(old, old.OFFSET + iter, _BYTE) AS _BYTE |
| iter = iter + 1: LOOP |
| |
| _MEMFREE old |
| END SUB |
| |
| FUNCTION getElementBYTE%% (o AS _MEM, element AS LONG) |
| getElementBYTE = _MEMGET(o, o.OFFSET + (element * cDT_BYTE), _BYTE) |
| END FUNCTION |
| |
| SUB setElementBYTE (o AS _MEM, element AS LONG, v AS _BYTE) |
| _MEMPUT o, o.OFFSET + (element * cDT_BYTE), v AS _BYTE |
| END SUB |
| |
| FUNCTION getElementINT% (o AS _MEM, element AS LONG) |
| getElementINT = _MEMGET(o, o.OFFSET + (element * cDT_INTEGER), INTEGER) |
| END FUNCTION |
| |
| SUB setElementINT (o AS _MEM, element AS LONG, v AS INTEGER) |
| _MEMPUT o, o.OFFSET + (element * cDT_INTEGER), v AS INTEGER |
| END SUB |
| |
| FUNCTION getElementLNG& (o AS _MEM, element AS LONG) |
| getElementLNG = _MEMGET(o, o.OFFSET + (element * cDT_LONG), LONG) |
| END FUNCTION |
| |
| SUB setElementLNG (o AS _MEM, element AS LONG, v AS LONG) |
| _MEMPUT o, o.OFFSET + (element * cDT_LONG), v AS LONG |
| END SUB |
| |
| FUNCTION getElementSIGL! (o AS _MEM, element AS LONG) |
| getElementSIGL = _MEMGET(o, o.OFFSET + (element * cDT_SINGLE), SINGLE) |
| END FUNCTION |
| |
| SUB setElementSIGL (o AS _MEM, element AS LONG, v AS SINGLE) |
| _MEMPUT o, o.OFFSET + (element * cDT_SINGLE), v AS SINGLE |
| END SUB |
| |
| FUNCTION getElementDBL# (o AS _MEM, element AS LONG) |
| getElementDBL = _MEMGET(o, o.OFFSET + (element * cDT_DOUBLE), DOUBLE) |
| END FUNCTION |
| |
| SUB setElementDBL (o AS _MEM, element AS LONG, v AS DOUBLE) |
| _MEMPUT o, o.OFFSET + (element * cDT_DOUBLE), v AS DOUBLE |
| END SUB |
| |
| FUNCTION getElementINT64&& (o AS _MEM, element AS LONG) |
| getElementINT64 = _MEMGET(o, o.OFFSET + (element * cDT_INTEGER64), _INTEGER64) |
| END FUNCTION |
| |
| SUB setElementINT64 (o AS _MEM, element AS LONG, v AS _INTEGER64) |
| _MEMPUT o, o.OFFSET + (element * cDT_INTEGER64), v AS _INTEGER64 |
| END SUB |
| |
| FUNCTION getElementFLT## (o AS _MEM, element AS LONG) |
| getElementFLT = _MEMGET(o, o.OFFSET + (element * cDT_FLOAT), _FLOAT) |
| END FUNCTION |
| |
| SUB setElementFLT (o AS _MEM, element AS LONG, v AS _FLOAT) |
| _MEMPUT o, o.OFFSET + (element * cDT_FLOAT), v AS _FLOAT |
| END SUB |
| |
_MEM have to be initialized before use, but they can be resized.