written by Sumbera, S., Nov. 2002
3. MDL Architecture
this chapter topics: Who should learn MDL, What means MDL, MDL framework |
![]() |
MDL is spine of MicroStation in term of programming. Anyone who wants to
develop professional applications for MicroStation should learn MDL.
MDL API is most complex API among other ones available by Bentley (like
MicroStation BASIC, MicroStationDGN COM object or JMDL classes)
Moreover you will find MDL useful if you are VBA developer because a lot of
MDL API may be used from Visual Basic too. We may say that MDL is something
like system-level programming while VBA is user-level programming in
MicroStation.
Conventional MDL
MDL doesn’t mean only a C derivate language for
MicroStation. We may take it as a framework for MicroStation development
containing all necessary features. It has its own compiler, linker, runtime,
graphical user interface and huge API covering all aspects for controlling
MicroStation.
MDL is the core application engine for MicroStation. Note we are speaking
about interpreted MDL or let's say conventional MDL.
Native MDL
'Native MDL' is free of all stuff like command line debugger, interpreted code, C restrictions or so... Native MDL is hosted by some IDE, has visual debugger, can be written in any language, run fast in native code etc.. simply all things you need and request as high-tech developer who is competitive nowadays in this childhood of new century. MDL is mainly set of API you use for full control of MicroStation.
We will look into MDL framework
MicroStation behaves as state machine. A state machine constantly watches
for events such as input events by mouse, keyboard, tablet, state change
events, timer events or others. When an event occurs, MicroStation checks
its current state and react on the event. This feature has major implication
on event driven programming in MDL.
An MDL runtime is a subset of MDL framework which supports the execution (but not the development) of MDL applications. The MDL runtime comprises the MDL Virtual Machine, exception handling, MDL debugger, MDL task management, system resource manager, dialog manager, task management and other supporting services.
Platform independence feature was indeed one of the reason why MDL source
code is not directly compiled into native CPU instruction but rather to the
pseudo code which is interpreted by MicroStation MDL virtual machine. This
imply that MDL programs cannot be run outside of the MicroStation.
MDL virtual machine is engine that acts as an interface or intermediate
level between binary MDL p-code and the microprocessor (or OS platform) that
actually performs the program's instructions.
This design has two advantages:
• System Independence: An MDL application is able to be run on different
platform regardless of the hardware or software underlying the system.
(unfortunately MicroStation v8 target only Windows platform)
• Security: Because the VM secure layer above the operating system, there is
little possibility of a MDL application damaging other files or
applications.
...and two disadvantages:
• API lowest common denominator: Because programs running in a VM are
separate from the operating system, they cannot take advantage of special
operating system features. MDL application do not look and feel like native
applications specific to the currently running operating system. Virtual
machine support the lowest common denominator. However there are many
platform-specific features and quirks that the users of specific platforms
expect. Even MDL API contain some Windows specific functions you can’t
expect to have full access to Win32 API function via the virtual machine.
Fortunately you may have this access through
native Dynamic Link Modules which are platform specific. A native
application can use these features producing an application that's faster,
looks and feels right, and works with the operating system and other native
applications as expected.
Although it was possible in previous versions of MicroStation to use native
code together with MDL, with MicroStation v8 this functionality has been
dramatically improved since the first release of MDL.
• Performance. The performance is lowered down due to the p-code
interpreter.
When programming with pointers you need to take care of the following facts:
• Pointers on data are real (native) pointers to MicroStation's data address
space and thus real pointers on operating system. These data pointers can be
shared with MicroStation, other MDL applications or native code if it has
privileges to read or write this memory. This feature may be seen as gap in
security of MDL Virtual Machine or as an advantage for MDL and native code
interoperability.
• Pointers on MDL functions are just offsets in the MDL program’s address
space, thus they are not real (native) pointers. They must point to MDL
functions (a sequence of pseudo codes produced by the MDL compiler) and
cannot point to native compiled functions. Fortunately MDL API provides
built-in function dlmSystem_callAnyFuncion for invoking MDL function
from native code or from interpreted MDL p-code.
• Pointers on native functions are in MDL also possible with
pointerToNative pragma. Note that DLL native functions symbols may be
simply imported into MDL code.
An exception indicates a fault in running application
requiring that the program responsible for the fault situation should be
closed. A fatal exception means the program can not continue to run. When an
exception is detected, MDL tries to report the exception type and tries to
abort the application. If application is compiled in debug mode, MDL runtime
enters into debugging the application whenever an error occurs.
Exceptions fall in two categories:
• Faults detected by MDL runtime: This may be caused by stack
overflow or divide-by-zero. This exceptions are usually easy to locate in
code and correct them.
• Faults detected by the native machine and operating system: For
example, if an MDL program causes a floating point exception or tries to use
a NULL pointer, a hardware exception occurs. MicroStation intercepts the
fault and performs its error recovery.
Bentley designed with Virtual Machine also platform independent symbolic, command-line debugger. Unfortunately this is the weak point of the MDL framework. The debugger can perform all necessary tasks, but is only “command line” friendly. If you prefer command typing with keyboard instead of mouse clicking you will be most satisfied MDL programmer. Despite this weakness after some experiences with debugging of MDL application you will find it even useful.
Executive code of interpreted MDL resides either in MDL application – a file with MA extension or in shared library – a file with MSL extension. We will briefly introduce them:
MDL application (MA)
resembles compiled and run able programs in system. Internally MDL application consists of an :
MDL program (MP) : required part of MDL application. An MDL program is created by compiling the source modules and then linking the object modules. Program is compiled into pseudo code, not native code. An MDL program consists of a 1. code segment – contains instructions understood only by the MDL pseudo code interpreter. These instructions are not documented at all and till now as far as I know no one has been able to decompile MDL program. So don’t worry, no obfuscation is needed and your source code is more protected than Java for instance. 2. data segment – contains some initialized data
Resources (RSC) : optional part of MDL application. resources are associated data fro MDL application such as GUI resources or language dependence messages.
MDL shared library (MSL)
resembles compiled dynamic libraries in system. A shared library is dynamically linked to MDL application. The MDL shared library has function and data symbols that are exported and can be used by other MDL applications. This is very similar to Dynamic Link Modules (DLLs), but again MDL shared library is compiled into pseudo code as MDL program.
MicroStation may load as many MDL applications as necessary. Every running MDL application is uniquely identified according following concept:
MDL task: is simply an MDL application loaded into memory by MDL runtime. MDL application need for operation different system resources, for example memory blocks, file handlers, symbol sets etc. System resources with corresponding loaded MDL application make up MDL task. Every MDL application also has a task ID. The task ID is an external name for the application as you see in file system. MDL task ends with unloading respective MDL application
MDL descriptor: Every task has associated structure called MDL descriptor used for tracking system resources and status of the MDL application. The format of the descriptor structure itself is not published. Wherever a pointer to an MDL descriptor is used, it just declared as void.
MDL process number: Both the task ID of an MDL application and the pointer to the MDL descriptor uniquely identify the MDL program. However if MDL application is unloaded, the task ID or MDL descriptor may be reused. In cases where it is absolutely essential that the identifier cannot refer to another task event after an application is unloaded, a MDL process number is used.
MDL context switch
A MDL task is either active in case MicroStation pseudo
code interpreter is executing its instructions, or suspended while
waiting to be activated by some event occurring in Microstation. If switch
to another MDL task is necessary, MDL runtime select target MDL stack, sets
the current MDL descriptor and starts executing the MDL task. This is known
also as MDL context switch. When MDL application calls a function within its
task, it means using normal symbolic reference or using function pointer -
that
call is called non-switched function call.
Note that there is no multi tasking in the interpreted MDL code.
..to be ..may be... continued
mail comments to stanislav@sumbera.com