The following figure shows the run-time architecture for accessing .NET objects using a sample ABL session instance to illustrate the run-time behavior.
Figure 2. .NET object run-time architecture
The entire session runs in a single ABL Virtual Machine (AVM)—a single prowin32.exe process in the Windows Task Manager. The AVM maintains two separate contexts:
The ABL context, which manages instantiation and execution of ABL procedures and classes
The .NET CLR context, which is an embedded CLR that manages instantiation and execution of all .NET classes on behalf of the ABL session
The ABL context functions like a client of the .NET CLR context. In other words, all actions initiate from a running ABL procedure or class. When an ABL action involves .NET, such as a reference to a .NET object type or any instantiation of and access to a .NET object and its members, the embedded CLR responds appropriately. When the .NET objects involved are .NET forms and controls, the ABL client then acts as a controller for the CLR-managed view.
So, in the above figure, the sample session starts out by instantiating the .NET class (ObjectA) which could be any accessible .NET object, such as a System.Windows.Forms.Button, or an ABL-derived .NET object, such as Acme.Controls.CustomButton (see Incorporation of the .NET object model). When this occurs, the CLR instantiates the working .NET instance and returns its object reference to ABL, which maintains it in an object reference structure. For an ABL-extended .NET class, the ABL object also contains the additional ABL code used to extend the .NET base class or implement a .NET interface. However, to an ABL application with an ObjectA that is an ABL-extended .NET class, both the ABL and .NET instances of ObjectA appear as one, which the ABL application accesses as if it were entirely managed by the ABL context.
ABL supports additional mechanisms required to handle many .NET features that are not supported for ABL classes, such as access to .NET inner classes. This allows an ABL session to appear and function similar to how it might if ABL were a fully CLS-compliant language. The difference consists in the .NET features that ABL does not support and the fact that the embedded CLR does not act on its own, except as initiated by the ABL session. This CLR has no direct knowledge of ABL context, nor can .NET classes interact with pure ABL objects as .NET objects.
Note, also, for any ABL-derived .NET class that overrides a method on the .NET base class, if .NET calls that method on the .NET instance using a super class object reference, the ABL-derived implementation of the method is executed with all results returned to .NET. For example, if ObjectA is an ABL-derived .NET class that extends System.Windows.Forms.Button, and ObjectA overrides the .NET ToString( ) method, it can perform any defined ABL processing and return its own CHARACTER value. If some .NET object running in the CLR references the .NET instance of ObjectA as a System.Windows.Forms.Button and invokes ToString( ) on the object, the ABL override of ToString( ) runs, not the .NET implementation defined for System.Windows.Forms.Button. After any ABL processing defined for ToString( ) completes, the resulting CHARACTER value of ToString( ) is returned to the .NET caller as a System.String value.
A similar effect can occur for an ABL class that implements a .NET interface. In other words, if ObjectA is an ABL-extended .NET class that implements a .NET interface. Some .NET object running in the CLR can reference the .NET instance of ObjectA as the .NET interface type that ObjectA implements. When the CLR thus invokes an ABL-implemented .NET method or accesses an ABL-implemented .NET property, it returns the results to the CLR as though these members were implemented directly in the CLR context.