In-Process and Out-of-Process Components

Microsoft Windows is now a full multi-processing operating system. Purists could argue that this was not strictly true with Windows 95, 98, and ME, but it has always been indisputably the case with Windows NT, Windows 2000, and is now the case with Windows XP.

Within the operating system, different applications can run concurrently within their own unique virtual address space. An application running in its own address space is called a Process. By having a unique virtual address space it would theoretically be possible for an application to write garbage into every memory location it could directly see, and the result would be only failure of the one process – other applications and the operating system itself would be unaffected. (This is a concept unfortunately lacking from AMOS). Within a process it is also possible to undertake several tasks seemingly simultaneously (or actually simultaneously if running on a multi-processor PC), by running separate sub tasks called Threads. Threads are of no direct concern to the A-Shell ActiveX SDK.

When a traditional subroutine or function is called by an application, all the parameters needed by the function are directly accessible by the function. That is because the function is running within the same process as the calling code, and has direct access to the memory in which the parameter values are held and where they need to be returned. The same is true when an in-process COM component is called and its properties and methods accessed, since an in-process component is loaded into the same process and memory space as the calling application. ActiveX DLL and OCX projects always compile and generate in-process components.

As well as in-process COM components, it is possible to create and access out-of-process components. An out-of-process component is actually a full executable program (EXE) which can typically be executed as a stand-alone application, but which contains classes which have methods and properties which can be accessed by other applications. Out-of-process components are accessed programmatically in exactly the same way as in-process components – this was one of the design goals of COM.

The process of controlling an out-of-process component was originally termed OLE-automation, or remote automation. This is because its original purpose was to allow a programmer to automate the operation of an existing application such as Microsoft Word.

When a method or property of a class in an out-of-process component is called, the code in the component is not able to directly access the parameters, as they are not present in the component’s address space – since this time the component is running in a separate process to the calling code. Instead, the data in the parameters is effectively copied between the processes’ address spaces using a procedure called marshalling. Because of this marshalling of parameter data (effectively additional memory-memory moves), out-of-process component access will always be significantly slower that in-process component access.

Within the context of the A-Shell ActiveX SDK, both types of component access are used:

• When controlling A-Shell from another application (via an instance of the A-Shell Application object), this is effectively remote automation, and A-Shell will be running as an out-of-process component.

• ActiveX XCALL routines written in Visual Basic are compiled as DLLs, and will consequently run as in-process components when they are called – running in the same address space of the A-Shell executable which called them.

Although no out-of-process parameter marshalling takes place when XCALL parameters are accessed from the Visual Basic code, data copying and moving does take place – this is because of the need to convert parameters between their AlphaBASIC formats and their Visual Basic data formats. Most significantly, floating point values are 6-byte under AlphaBASIC but 8-byte under Visual Basic, while strings are ASCII and use a single byte per character under AlphaBASIC but are UniCode and use two bytes per character under Visual Basic.