Here we create DEFSTRUCT in a string variable, including a couple of dependent DEFSTRUCTs, DEFTYPEs, and DEFINEs, and use it to define a dynstruct.
map1 dsdef$,s,0 ! string to hold definition source
map1 fields,i,2 ! # fields (signed to allow error codes)
map1 stsize,b,4 ! size of the structure
map1 errmsg$,s,100 ! error messages
map1 lf,s,1,chr(10) ! line terminator for structure lines
! Start with some preliminary definitions…
dsdef$ = "deftype T_SKU = s,10" + lf &
+ "define LEN_NOTES = 30" + lf
! now define structures on which our Dynstruct will depend
dsdef$ += "defstruct ST_PRICE" + lf &
+ "map2 cost,f,6" + lf &
+ "map2 wholesale,f,6" + lf &
+ "map2 retail,f,6" + lf &
+ "endstruct" + lf
dsdef$ += "defstruct ST_DUMMY" + lf &
+ "map2 manny,f,6" + lf &
+ "map2 moe,f,6" + lf &
+ "map2 jack,f,6" + lf &
+ "endstruct" + lf
! finally the Dynstruct we are defining...
dsdef$ += "defstruct ST_TEST" + lf &
+ "map2 qty,b,2" + lf &
+ "map2 sku,T_SKU" + lf &
+ "map2 price,ST_PRICE" + lf &
+ "map2 notes(4),s,LEN_NOTES" + lf &
+ "endstruct" + lf
fields = Fn'Dynst'Define(dsdef$,stsize,"ST_TEST",errmsg$)
? " status: ";fields
if fields < 0 then
? " status (fields): ";fields;" ("+errmsg$+")"
else
?
? " structsize: ";stsize
? " # fields: ";fields;" (including overall structure)"
endif
The above example uses a convenience wrapper function from fndynst.bsi in SOSLIB:[907,10] to handle the actual MX_DYNSTRUCT to define the dynstruct, the source of which is here:
Function Fn'Dynst'Define(dsdef$ as s0:inputonly, &
stsize as i4:outputonly, &
dsname$ as T_DYN_NAME:inputonly, &
errmsg$ as s0:outputonly) as i4
map1 locals
map2 status,i,4
map2 fields,i,4
xcall MIAMEX, MX_DYNSTRUCT, DYNOP_DEF, status, dsdef$, fields, stsize, dsname$, errmsg$
if status >= 0 then
Fn'Dynst'Define = fields
else
Fn'Dynst'Define = status
endif
xputarg @stsize
xputarg @errmsg$
EndFunction
The function doesn’t add much value but does isolate the application somewhat from the technical details of the dynstruct definition process, which could be subject to change in the future.
Note that at this point we’ve defined the dynstruct ST_TEST and can refer to it by its name ("ST_TEST") at any pointer later in this program, i.e. to bind it to a dynstruct variable, retrieve layout information about it, etc.