It is All about Traffic, and Programming
Search
Archives
0 visitors online now
0 guests, 0 members

VISSM COM Instance Model

This post has already been read 706 times!

VISSIM has a licensed feature “VISSIM COM” that a user can use to do automation-style programming. It provides convenient, easy-to-use  interfaces to access VISSIM functionality programmingly (e.g., though an Excel client).

VISSIM COM Server by design can only be invoked in “single instance” mode. That is, if you have a COM client that tries to establish a connection with a VISSIM COM server, the connection will be established only to the first VISSIM instance that has already been created.  In other words, a new VISSIM instance is created if and only if there is currently no active VISSIM instance running.  On the other hand, if there are multiple VISSIM instances, your COM client would only connect to the first instance.

Yesterday at  the 90th TRB annual meeting, a Minnesota friend asked me if it is possible to create multiple VISSIM COM server connections.   That was a pretty interesting question, and the answer lies in a clear understanding of what is under the hood of Microsoft’s COM technology.  Probably  let me do a little lecture first for those non-programmers or who not familiar with the inner workings of COM.  Since in 99.9% of its applications,  VISSIM is only used as a local out-of-process COM server,  let me just focus on explaining out-of-process COM only.  In-process COM has somewhat different mechanism – in order not to confuse I’ll rather leave it to some discussion later.

For out-of-process COM exe server like VISSIM,  a client program (a client program can be written in any COM compliant languages such as VB, VC++, .NET, or Delphi) starts a connection by calling Windows Operating System’s COM API in the following sequence:

1. CoCreateInstance

Nothing need to mention about this COM API.

 2. CoGetClassObject

For In-Process COM object, CoGetClassObject will get the pointer to the class factory; but for out-of-process COM exe like VISSIM, CoGetClassObject will get the VISSIM path from the ProgID in the system registry. Note, different versions of VISSIM has different ProgID. Also remember VISSIM is registered a LocalServer, so no DCOM is involved.

 3. CoRegisterClassObject

Once the system locates VISSIM.exe, CoRegisterClassObject (this is the ultimate ole32 API to be invoked, even VISSIM uses some .NET wrappers) – will be invoked in the start-up code before calling the WinMain entry function of VISSIM.exe.

 Here is the signature CoRegisterClassObject(CLSID, pUnk, dwClsContext, flags, &dwRegister). The key point is the fourth parameter “flags”. It determines during run-time whether VISSIM COM exe can be started as single instance or multiple instances. Check MSDN for more information about this COM API:

http://msdn.microsoft.com/en-us/library/ms693407%28VS.85%29.aspx

The fourth parameter is a REGCLS enumeration variable defined as:

typedef enum tagREGCLS { 
  REGCLS_SINGLEUSE       = 0,
  REGCLS_MULTIPLEUSE     = 1,
  REGCLS_MULTI_SEPARATE  = 2,
  REGCLS_SUSPENDED       = 4,
  REGCLS_SURROGATE       = 8
} REGCLS;

All we need to do is to  specify REGCLS_SINGLEUSE,  then VISSIM COM exe will be invoked in a “multi-instance” manner.  Why? Here is the description of the REGCLS flag:

  • REGCLS_SINGLEUSE

After an application is connected to a class object with CoGetClassObject, the class object is removed from public view so that no other applications can connect to it. This value is commonly used for single document interface (SDI) applications. Specifying this value does not affect the responsibility of the object application to call CoRevokeClassObject; it must always call CoRevokeClassObject when it is finished with an object class.

  • REGCLS_MULTIPLEUSE

Multiple applications can connect to the class object through calls to CoGetClassObject. If both the REGCLS_MULTIPLEUSE and CLSCTX_LOCAL_SERVER are set in a call to CoRegisterClassObject, the class object is also automatically registered as an in-process server, whether or not CLSCTX_INPROC_SERVER is explicitly set.

The above text is a little twisty – essentially it says, if REGCLS_SINGLEUSE is set, then any client connection request would result in creation of a new class object – in our case, the class object is VISSIM object represented by IVissim interface. Creating a new class object means starting a new VISSIM.exe process, because VISSIM.exe is the host of the class object. Period.

A little interesting additional information on what happens after CoRegisterClassObject – Internally, a I/O completion port (a.k.a IOCP) is created.  I/O completion port is a fairly low level Inter Process Communication (IPC) mechanism. By low level, I mean, File handle, Winsock2, name pipes etc all these higher level IPC mechanism would be built on top of I/O Completion port. So IOCP is pretty “ugly” if you ever bother to delve into that level to satisfy your peeking eyes and curiosity.

The created I/O completion port receives I/O completion packets then dispatches the package via Windows messaging then to the WndProc registered by ole32.dll. That WndProc then unmarshall the out-of-process COM method invocation and restores the original function’s stack frame, hence finishes the entire invocation COM function.

This creation of stack frame on the fly is similar to how web services are implemented. All are based on stack frames created during run time. Stack frame is just a memory footprint to prepare a function invocation, say, you need to allocate sufficient memories from the stack, then save all the current states registers and push the parameters. Of course, in COM, the convention is always stdcall.

Depending on the threading model the subject COM objects implements (single apartment, multiple apartment or whatever), there are some nuisances that I am not going to touch here.

This post has already been read 706 times!

Leave a Reply

Your email address will not be published. Required fields are marked *