Any way to do run-time type casting?

Is there any way to typecast a memory reference to the proper type if the proper type is known but in string form?

An example use would be:

Buffer b = castFunction("Buffer", someMemoryReference);

 


At first I thought the eval_() function looked promising. The eval_("myCode") function only returns strings and runs in another context. Not looking good.

An example use would be:

 

 

delete( (Buffer someMemoryReference) );


only I don't know at compile time (coding time) what the cast should be.

I know I can always have an exhaustive list and IF them all out like:

 

 

if (typeOfMemRef == "Buffer") {
    delete ( (Buffer) someMemoryReference );
} else if (typeOfMemRef == "Array") {
    delete ( (Array) someMemoryReference );
} // and so on



Is this the above the only way? Has anyone found a solution for DXL run-time casting based on a supplied string parameter?



 


SystemAdmin - Fri Apr 02 14:25:39 EDT 2010

Re: Any way to do run-time type casting?
SystemAdmin - Fri Apr 02 14:42:37 EDT 2010

Elements of DxlObjects can point to anything. You could have one element be the thing, and another be the type.

Re: Any way to do run-time type casting?
Mathias Mamsch - Fri Apr 02 15:48:14 EDT 2010

Hmm ... thats a hard one ... DOORS DXL is highly polymorphic, meaning there can be lots of functions that have the same name but different parameters. The DXL parser will determine the right function to call by looking at the parameters and it will do it before the code even starts running. So there is no other chance than putting a call to each function in your code and surround them by ifs. Once your code starts running the DXL interpreter already decided which function he will call. BUT: There is a way to get around this. Since DOORS does not protect its memory and every DXL program might run in the same DXL context, but does share the same DOORS process memory one DXL code can poke around in each others code. So we can use eval_ to create our DXL code at runtime and decide at runtime what type we will use:
 

// A buffer and an array
Buffer s = create() 
Array a = create(1,3) 
 
void polymorphicDelete (int ad, string type) {
     string code = "int mem=" ad "\n" type "& var = addr_ mem; delete var; var = null"
     print "Running code: " code "\n"
     eval_ code
}
 
s = "Test"
 
print stringOf s
 
// this is the hard part ...
polymorphicDelete ((addr_ (&s)) int, "Buffer") 
polymorphicDelete ((addr_ (&a)) int, "Array") 
 
print "Buffer was set to null: " (null s) "\n" 
print "Array was set to null: "(null a) "\n"

 


The syntax of this code might be a little hard to get. First you need to know the _y addr_(_x) perm which will "type-cast" any data type at runtime to another datatype ... Then you need to know the _k* ::(&) (_k&) perm which will return a pointer (just like in C) to a datatype. What the code (&s) does is get a pointer to the Buffer variable on the DXL stack. Remember in C that pointers contain the address of a variable. The same is true in DXL. Afterwards I cast the pointer to the buffer to an integer (which is the memory address on the stack) using the (addr_ (&s) ) int. This memory address is put into the DXL code that will be executed from eval_. For a buffer it would look like that:

 

 

 

Buffer& var = addr_ mem; 
       delete var
       var = null



Notice that the code contains a reference to the buffer, so that I can set the buffer variable to null and the change will carry over to the main program. While this is pretty cewl it seems to mess up DOORS internal memory allocation for DXL programs. This code runs only once, the second time it seems to crash. So I would not do memory allocation and deallocation using that mechanism, but for most other things you should be fine.

Regards, Mathias