WuPiN G XiN BloG

It is All about Traffic, and Programming



0 visitors online now
0 guests, 0 members
1 2 3 6

Dissecting Vissim COM Internal from Inside Out (4) – a “Loophole” for a Perfect Solution

Previously I have a series of articles on “Dissect Vissim COM Internal from Inside Out”. You are welcome to re-visit them:

You are also welcome to re-visit another previous article of mine, which provides somewhat in-depth coverage of Vissim COM Instance Model.

  • Those articles are pretty technical but provide quite a bit of insights on how Vissim COM is designed and how it works. They were originally motivated by the single question: How to access Vissim COM interface data during run-time from inside a DLL, e.g., External Driver Model DLL, or Signal Control API DLL?

In these articles, various techniques were discussed to address the above question. However, these techniques require deep knowledge of Assembly language, Microsoft Component Object Model, and other techniques that may not be practical for ordinary Vissim users.

Today, let me introduce an easy and effective approach, of accessing ANY Vissim COM interface data from any Vissim-loaded DLLs (such as External Driver Model DLL, Signal Control API DLL or Emission Model DLL etc).

This approach is based on a “loophole” of Vissim’s COM interface design; the “loophole”, as we call it, may not be originally planned/intended as a common use case of Vissim COM applications, and yet it is a workable trick that we can utilize to our “convenience”.

To accomplish what just said, we need to use Vissim Event-based COM script. As you may have already known, Vissim Event-based COM scripting is a handy feature that allows you to write scripts in VB, Python and JavaScript.

Oh… Wait, as a matter of fact that may surprise you – it does allow you to write scripts in ANY language registered as the Active Scripting Engine on the Windows Script Host that comes with the Windows Operating System.

In short, Vissim Event-based COM scripting is really based on the Active Scripting technology. An end user can access Vissim’s interval COM interface objects via a hosted scripting engine such as Python or JavaScript. Any script running by Vissim is sharing the SAME memory space as the Vissim host.

And from inside the script, you have access to almost all of Vissim COM interface objects properties and data. You can also invoke any COM object’s interface methods – Vissim COM objects implement IDispatch interface so the script can invoke the methods by their symbolic names (rather than by their direct memory address, hence, slow).

The above facts render a new approach to pass any Vissim COM interface data to a DLL, such as Vissim External Drive Model DLL, or Signal Control API DLL. Until this point, you will probably have recognized immediately that this opens a whole new world of opportunities for really powerful and cool applications.

OK. Enough talk. The following are illustrative steps that have been tested, and just works!

STEP 1: Write the following Python script – as you can see, it is named as “ComDataExport.py”.

STEP 2: Export a new function from External Driver Model DLL “CallFromComScript”.

STEP 3: Add the script to Vissim simulation model as below

STEP 4: Assign the External Driver Model DLL to a vehicle type. And that is it. You can send ANY COM interface data to the Driver DLL!

Now that you have read to this point, you will see that this essentially creates a “tunnel” between Vissim COM interface and the target DLL. In this case, the target DLL is the External Driver Model DLL, but it could something else with your imagination and creativity.

The beautiful thing is, because the script is “event based”, i.e., it is invoked by “event” such as “beginning of simulation step”, you can actually have very fine-grained control of this data pass-through process.

I am excited. Are you?

One caveat: we can only use this approach to pass Vissim COM interface data (property value). You won’t be able to pass through references (memory addresses) of COM interface methods (because the COM interfaces in the script namespace are really …. “marshaled” active scripting items, not real objects)

Why, is this a “loop hole”? You may ask with a smile, finally. Well …… it is called a “loophole”, in the sense it is not part of the “original” design. It also provides an extra mechanism for “DLL Injection” beyond the scope of this article.

OK. That is good enough. Be Creative, and have fun.

Who touches my “for-loop” condition?

A for loop is a common control structure that allows repetitions of certain statements for a specific number of times. The syntax of a for-loop in C++ or C# is

for (initialization; condition; increment) {

As simple as ABC. As easy as a no-brainer. As happy as Clam.

Now, look at the following C++ code. How many times would the the loop execute?

int main( )
   int N = 10;

   for ( int i = 0; i < N; i++ ) {
     std::cout << "i = " << i 
               << ";"
               << "N= "  << N 
               << std::endl;

   return 0;

As the output shown below – The loop executes 5 times, even though we set N = 10.  Obviously, modifying N inside the loop body, i.e., N–, causes the termination of the loop prematurely.

Generally speaking, it is a bad practice to modify loop termination condition inside a for-loop. Bad, Bad, Bad!

Now, the same question for a similar Delphi code:


  I, N: Integer;

    N := 10;

    for I := 0 to N do
      WriteLn( Format('I=%d, N=%d',[I, N]) );
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);

The output is not so much unsurprising – unlike the C++ counterpart, it does loop 11 times:

Interesting. It seems modifying N inside loop body doesn’t impact the number of intended loop execution times.

Let’s check the disassembled C++ binary:

As seen from the highlighted lines, N is referenced by address (i.e., ptr [N]) in loop body. This means, any change to N’s value will eventually impact the termination condition evaluation. Address [ebp-14h] is the local variable i stored in Stack, which is incremented with every repetition of the loop, before comparing to ptr[N] that is decremented with each loop.

Delphi compiler generates something different:

N is addressed at [0x004258a8]. At the beginning of the loop, N’s value is copied to [$ebp-$14]. Each loop just checks [$ebp-$14] for termination. Modifying the original Nwouldn’t impact the loop termination condition evaluation.

So, though it is generally not a good practice to change for-loop termination condition inside the loop,  Delphi obviously has some compiler caveat that may slip the mind of a careless programmer. Be warned!

Lane Closure Utility Updated for VISSIM 9

Lane Closure Utility was initially developed in 2006 as an amateur/hobby work by a then graduate student.  Surprisingly,  it had been found useful,  and has been used by quite a few industry engineers, graduate students,  and academic researchers in their work.  I would like to thank them again for giving me feedback and inputs.

I just updated this free little utility to work with VISSIM latest 9.x version.

PTV made a LOT, really a LOT of changes to VISSIM COM interfaces – which is annoying but understandable given their grand plan of overhauling and refactoring the system’s application framework inside out –  that however made this upgrade quite eventful trying back and forth to figure out a lot of undocumented changes. Anyway,  I managed to just upgrade the code to match the latest VISSIM version COM interfaces.

It can be downloaded here: vissim9-dist-x86-x64  Feel free to download and distribute.

For those interested – my previous post about this little utility is here, so you can learn how to use it (easy and simple!)  Another big surprise to me as I found today is that – the original post has been read for almost 5000 times!  Wow.  I would be even happier  if you’d left me some comments,  good or bad.

Lane Closure Utility for VISSIM 5.40 (32bit and 64bit)


The Move Constructor: A Linking Pitfall of Qt Library with Different Compilers

Move constructor is a C++11 feature from ISO/IEC14882:2011.  It enhanced the old-school C++ copy constructor by moving the resource of an object, instead of member-wise copying.  It is faster than a copy constructor.  Thus a C++11 compiler will generate six special member functions for a C++ object, including  move constructor and move assignment operator:

  • Default Constructor
  • Copy Constructor
  • Copy Assignment Operator
  • Destructor
  • Move Constructor
  • Move Assignment Operator

We are not going to discuss C++11 Move Constructor in details here –  better details and better explanations are there, and there.

The motivation of  this article,  is not to discuss the semantics or usage of Move Constructor,  but an interesting debugging experience, and the lessons learned which involves C++11 move constructor.

Long story short – I have been working on developing an advanced Qt-based C++ plugin DLL for a host software developed in Qt 4.8.7.   I was using Visual C++ 2010 compiler, and the Qt for VS2010 official release for commercial applications.

The plugin DLL is supposed to be dynamically loaded by the host via Qt’s QLibrary API (see my previous article on this subject), which internally will call Microsoft’s Win32 API LoadLibrary.  Somehow, I got the following error, when trying to load the DLL into the host software:

34f8:3518 @ 01570140 – LdrpGetProcedureAddress – INFO: Locating procedure “AcdssPluginFactory” by name
34f8:3518 @ 01570140 – LdrpNameToOrdinal – WARNING: Procedure “AcdssPluginFactory” could not be located in DLL at base 0x0B630000
34f8:3518 @ 01570140 – LdrpReportError – WARNING: Locating export “AcdssPluginFactory” for DLL “Unknown” failed with status: 0xc0000139
34f8:1168 @ 01570265 – LdrpReportError – ERROR: Locating export “??4QString@@QAEAAV0@$$QAV0@@Z” for DLL “C:\Program Files (x86)\…\plugins\acdssplugin.DLL” failed with status: 0xc0000139

The above debug messages were generated by GFlags Utility, which comes with Debugging Tools for Windows. You can find the most advanced debugging techniques including how to use GFlags utility from the excellent book Inside Windows Debugging.  In our case, we just need to set “Show Loader Snaps” flag, as shown in the figure.  This is a typical way of debugging LoadLibrary failures.


Looking at the debug messages, it is simply pointing out that LoadLibrary fails because an exported function is missing from the image space – its C++ mangled name as  “??4QString@@QAEAAV0@$$QAV0@@Z”,  which can be interpreted as:

    ? = C++ mangled symbol
    ?4 = "operator="
    QString@ = the enclosing class, hence method name: QString::operator=
    @ = end of the scope
    Q = public
    A = no const and volatile qualifier
    E = __thiscall
    AAV0 = const ref to the first named class (QString) - the return value (const QString &)
    @ = end return type
    $$ = move constructor &&
    QAV0 = const pointer to first named class - QString * const
    @ = end parameter type
    @ = end parameters
    Z = function

So clearly, the host software was complaining that the Move Constructor of QString can not be located in any of the image space.  Upon further inspection of the host software, it is discovered it was compiled using VS2005.  QtCore4.dll does not have the Move Constructor generated with VC++ 2005 compiler.  

The solution is simple – just rebuilt the Qt 4.8.7 using VC++ 2005, and rebuilt the plugin DLL.  Above all, the lessons learned are:

Do NOT mix Qt library compiled with different compilers, EVEN with the same Qt Version.  Period.

VISSIM in VMWare: USB Passthrough Timeout with WiBu CodeMeter

Starting with VISSIM v8,  the CodeMeter dongle stores more licensing items than earlier versions. This may result in USB pass through timeout when running VISSIM from within a VMWare virtual machine.  We discuss this potential issue here and a fix is documented.

In a previous post, we have discussed running VISSIM in a VMWare Workstation  virtual environment:



This should be working fine until PTV released VISSIM 8.0,  which is a great upgrade to v7 with a lot of nice additions and enhancements, especially the mesoscopic traffic simulation, to name just the most note-worthy.

For users of VISSIM v7,  the upgrade to V8 requires one unusual step to update the contents of the CodeMeter key.  And PTV apparently has more to feed into the dongle than old versions, thus after upgrading to VISSIM v8 with the “stuffed” CodeMeter dongle,  you might have problem launching VISSIM in a VMWare virtual machine,  something like this:  the code meter icon shows up in a yellowish-green color different than the normal color, while VISSIM complains “CmContainer entry not find Error 200”:2016-02-15_12-44-04










It is even more perplexing that there will be no problem running VISSIM with the same CodeMeter dongle, but on a direct physical computer. The virtual machine that you might encounter this issue includesWindows Server 2012 R2, Windows 10 x64 Pro. However, Windows 7 x64 virtual machine has no problem.

And you might see CodeMeter log output as follows:

2016-02-15 15:16:57: CodeMeter for Windows (B6.10.2018.501.32.180)
2016-02-15 15:16:57: Running on Microsoft Windows 10 Pro, 64-Bit
2016-02-15 15:16:57: Execution path: C:\Program Files (x86)\CodeMeter\Runtime\bin
2016-02-15 15:16:57: Found IPv4 address: |
2016-02-15 15:16:57: Found IPv6 address: ::1 | fe80::a45b:71d5:41d1:150%3
2016-02-15 15:16:57: Used Communication Mode: IPv6 IPv4 SharedMemory
2016-02-15 15:16:57: Used IP address: default address
2016-02-15 15:16:57: Used IP port: 22350
2016-02-15 15:16:57: Used CmWAN port: 22351
2016-02-15 15:16:57: Multicast server search: not available
2016-02-15 15:16:57: Run as network server: no
2016-02-15 15:16:57: Run as CmWAN server: no
2016-02-15 15:16:57: Run as system service: yes
2016-02-15 15:16:57: Service startup delay:  0:08 minutes
2016-02-15 15:16:57: Box Access: use direct access mode
2016-02-15 15:16:59: Detecting CmContainer with Serial Number 2-2573687
2016-02-15 15:17:16: Runtime Event RT410-535 (2573687) occurred.
2016-02-15 15:17:46: Runtime Event RT410-535 (2573687) occurred.
2016-02-15 15:17:46: EBL-Trace: I1P1CX1CX1
2016-02-15 15:17:48: Event WB0407 (REPLUG) occurred: RePlug(2)
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 16)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 16 released
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 17)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 17 released
2016-02-15 15:17:48: Access from local(IPV6) to SubSystem (Handle 18)
2016-02-15 15:17:48: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:48: Handle 18 released
2016-02-15 15:17:48: Box Event HW04-529 (2573687) occurred.
2016-02-15 15:17:49: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 22)
2016-02-15 15:17:49: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 26)
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 27)
2016-02-15 15:17:49: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:49: Handle 27 released
2016-02-15 15:17:49: API Error 115 (WRONG HANDLE TYPE) occurred!
2016-02-15 15:17:49: Access from local(IPV6) to SubSystem (Handle 31)
2016-02-15 15:17:49: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:49: Handle 31 released
2016-02-15 15:17:55: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 35)
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 36)
2016-02-15 15:17:55: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:55: Handle 36 released
2016-02-15 15:17:55: API Error 115 (WRONG HANDLE TYPE) occurred!
2016-02-15 15:17:55: API Error 105 (INVALID PARAMETER) occurred!
2016-02-15 15:17:55: Access from local(IPV6) to SubSystem (Handle 40)
2016-02-15 15:17:55: API Event WB218 (NO LICENSE AVAILABLE) occurred (returned to caller)
2016-02-15 15:17:55: Handle 40 released

The problem  is really caused by USB timeouts when reading a large quantity of licenses.  This happens when CmStick uses the VMWare USB pass-through communication mode between CodeMeter Run-time Server (that is running inside the virtual machine) and CM-Stick (that is plugged via the host physical computer’s USB port).   That is why I believe that PTV has added a lot more license items into the CmStick than earlier versions, since this didn’t happen before.  The solution (thanks to the heads up from Mr. John Battista from WiBu USA) is to use the “File I/O” communication mode (UseUmsDA = 0) :

CodeMeter communication mode (on the virtual machine) can be changed  as follows:

1. In the virtual machine Guest OS, open the windows registry using regedit.exe


3. Set the “UseUmsDA” variable to 0

4. Restart CodeMeter Service, or restart the virtual machine directly

Then everything is working again.  Have fun!

Adaptive Signal Control: Cyclic, or not?

At LinkedIn Group Adaptive Traffic Signal Control Systems,  Dr. Andrei Reztsov,  an applied mathematician posted a link for his new paper

Self-Organizing Traffic Lights as an Upper Bound Estimate
Andrei Reztsov, Complex Systems 24(2).


Self-organizing traffic lights (SOTL) are considered a promising instrument for the development of more adaptive traffic systems. In this paper we explain why some well-promoted results obtained with the use of SOTL should be scrutinized and carefully reviewed. Current computational research projects based on SOTL should be reviewed too.


For those interested,  Dr. Reztsov’s papers can be downloaded from SSRN.

I applaud this paper for its insights and for its logical and rigorous treatment from an mathematician to point out the methodological fallacies of SOTL or those type of second-by-second genre of real time signal control. I concur with the opinion of the paper. As far as I know, this appears the first to discuss the following aspects of adaptive signal control:

  • cyclic calculation/decision,
  • sub-cyclic calculation/decision, and
  • sec-by-sec decision.

Self-Organizing Traffic Light (SOTL), or sometimes  “Second-By-Second” control  refers to acyclic operations by internally manipulating phase force-off and phase hold commands so the signals do not operate on a cyclic basis. It is “second-by-second”,  in the sense the system monitors phases status and detectors inputs continuously,  and makes decisions to terminate or extend phases on a second-by-second or near second-by-second basis.  These are currently not within standard NTCIP C2F operations.

A centralized second-by-second control typically would result in high communication overhead due to the onerous second-by-second status monitoring at each individual phase and/or detector level. Also second-by-second control cannot be easily integrated with current NTCIP Center-2-Field framework, because  NTCIP is UDP based type of communication that cannot guarantee the receipt of data packets, thus not meeting the reliability requirement for second-by-second control. In practice it is typically implemented in a distributed manner at local controllers, and requires certain middle-tier mechanism (e.g., a field master, or a customized firmware embedded in the same cabinet, or an add-on module communicating with a standard SDLC port) to coordinate with adjacent intersections and cache the second-by-second commands without overwhelming the central system, if any.

Second-by-second type of control is flexible,  and effective when traffic demand is low to the extend of random arrivals. It is most effective when the network starts with empty streets – that is exactly where this type of control’s niche resides to best reshuffle the time resource – to accommodate the predicted arrival of platoons on a preferred route. It works well, only and only when there is time resource to exercise such “rescheduling”.

And that is  the problem.

The traffic signal optimization problem is fundamentally simple – it boils down to allocate either limited time resource (for oncoming vehicles),  or limited space resource (for queuing vehicles),  of at-grade intersections with competing traffic streams.

“At-grade intersections” means the system has to deal with competing traffic streams in a 2-D plane.  Both time and space resources are limited for at-grade intersections.  Time resource is limited,  because in practice  any at-grade intersection’s capacity will never exceed 1800 vphpl; space resource is limited, because it is constrained by available storage space.

The signal for each phase applies to the group of drivers, not an individual driver on an individual stop-release basis. When traffic is light,  the signals running second-by-second can favor the predicted on-coming traffic on a preferred route,  thus reducing perceived maximum waiting time for individual drivers, and improving individual driver satisfaction.

The challenge really comes when traffic becomes heavy and over-saturated.  In that case,  the available capacity of an intersection is not able to serve the demand, and the flexibility to shuffle the time resource for vehicle platoons is gone.

It is logical to believe that when traffic is light to the extent of pure random Poisson arrivals, SOTL behaves more like an enhanced actuated type of control; when traffic increases, SOTL would converge to cyclic no matter how the logic tries to reshuffle the time for individual vehicles.  The chain of reasoning is:

When traffic is light, the value of sec-by-sec may help individual driver  satisfaction due to its flexibility to freely terminates a phase, and due to the reduced MAX perceived delay time, but not primarily average delay. However, when demands increase, the benefits quickly diminish and average delay increases.  At certain range of traffic flow regime, sec-by-sec control  probably reduces capacity because of the increased lost-time from phase switches.  Remember,  phase switches have a cost of lost time which is non-trivia when traffic is not light.  Therefore, with traffic increasing, sec-by-sec will quickly converge to cyclic losing its point.

This explains my particular favor of a cyclic system and I found this paper is very interesting.

Convergence to cyclic and the effect of sec-by-sec of reducing MAX perceived delay instead of AVG delay renders such operation moot in practice, because:

  • When traffic is light as random arrivals, there is really not much need or systematic benefits of  running adaptive.  This is because a fully actuated setting can well handle light traffic conditions.  Favoring a route when traffic is light may well promote speeding and incur other  implications.

This also explains why sec by sec control by itself wouldn’t be working well for congested or heavy traffic, at least not as well as some of the literature reported.  It appears to me many before-and-after improvements were built on the base case of comparisons being poorly-tuned fixed time plans,  or not well-configured semi-coordinated operations.

In summary, using comments posted in the same LinkedIn Group, from Mr. Kevin Fehon:

It is logical that SOTL or similar systems must converge to a cyclical state with heavy demand and practical constraints (such as maximum wait time, driver expectations about fairness in distribution of delays, etc.). This is built-in in their operations, and  is supported by observation of existing non-cycle based systems in the field.  It appears that this convergence also cannot be as optimized as the operation of a system whose optimization assumes cyclical operation, especially when vehicle-actuated flexibility (phase re-service, phase sequence changes under different traffic conditions, etc.) is built into the system.

Dissecting Vissim COM Internal from Inside Out (3)

In order to study the life cycle of CCOMVissim,  we have to track the calling stack of comsvr.dll.  This DLL is the host of CCOMVissim and other helper classes of Vissim COM functionalities. Please note it is not possible and not an option to perform static code analysis using a typical debugger. This is because CodeMeter hardware chip employs sophisticated anti-debugging mechanism, black-listing all known static/dynamic analysis debuggers such as OllyDBG or IDAPro .  We’d have to return to comsrv.DLL  – and recall in this post – the 58 exported functions, something like below:


As an effective approach (for interoperability among Vissim’s own various licensed modules),  let’s start creating a DLL project, using the same name “comsrv.DLL”,  as the one in the Exe folder of Vissim installation.

As a good background reading on exporting  C++ classes in a DLL,  here is an detailed post CodeProject: Export C++ classes from a DLL

Following this new Visual Studio C++ DLL project,  create a new class called CCOMVissim  – pay attention to the class definition, and the empty methods, and the declaration “__declspec(dllexport)“.  By default, the calling convention is “thiscall“.  Because we know Vissim is compiled in Visual C++ compiler apriori, thus name mangling wouldn’t be an issue (because of the same C++ compiler).


Now, compile this project, and a dll called comsrv.dll is generated.  After this new DLL is generated,  de-compile it to verify the exported functions (see the figure below):


We just created a “proxy” DLL with the same name as Vissim’s original comsrv.dll.  We emulated some of the original exported functions and classes.  The point is,  as long as the same list of  functions  are exported by this new dll, it is “loadable” by Vissim.  Therefore, we are  enableed to append additional code to track, manage, and manipulate the calling stack of those class methods or functions relevant to the life-cycle of IVissimPtr. This will help accomplish the objective of enabling interoperability of Vissim COM functionalities within Vissim’s various DLL-based modules,  including Signal Control API DLL, External Driver DLL and such.

If you could understand up to this point,  there should be no problem for you to move on to a final working solution to the question asked in the beginning.  The efforts are yours, and the omissions are mine.  One last hint:

Rename the original “comsrv.dll” to a different name, e.g., “comsrv_org.dll”.  Redirect calls from inside the proxy comsrv.dll to the original dll.

Dissecting Vissim COM Internal from Inside Out (2)

Let’s look at a typical Vissim COM programming code snippet in C++. It is taken from the Vissim manual, with some reformatting.

For Vissim end users, C++ is not an ideal choice of language for COM applications.  You’d have to handle all the complexities involved with COM  interface management. C++/COM programming has never been something as easy as a breeze with a steep learning curve.  On the other hand,  C++/COM is excellent that it does not hide COM implementation details,  while providing the best performance than any other languages. It is simply native to the COM world.


In this beautiful C++ code snippet, Smart Pointer is used.  QueryAttach is a helper function shipped with this sample; it encapsulates the tedious QueryInterface process, and wraps up the returned Vissim interface as a smart pointer.

Clearly, the code illustrates the work-flow invoking Vissim as an automation server (see my another post on Vissim COM Instance Model).  When you call CreateInstance,  a Vissim process is started, where the default interface IVissim is instantiated and returned as the smart pointer IVissimPtr.

To say the least,  IVissimPtr is the “Open Sesame” to the wonderland of Vissim COM programming.

The  flow of all Vissim COM programming starts from getting an instance of IVissim interface.

It is fairly easy to get an IVissim interface by invoking Vissim as an automation server – just having an external COM client to call   CreateInstance.

VISSIMLIB::IVissimPtr pVissim declares the smart pointer to the default  IVissim interface.  COM smart pointer encapsulates COM operations including AddRef, Release etc. Don’t confuse yourself VISSIMLIB::IVissimPtr with IVissimIVissimPtr is generated by macro _COM_SMARTPTR_TYPEDEF(IVissim, __uuidof(IVissim)), while IVissim is declared as the following:

struct __declspec(uuid("a023e2ec-8002-4bb1-a584-b85ce59681ee"))
IVissim : IObjectBase
    // Property data

    INetPtr Net;
    ISimulationPtr Simulation;
    IEvaluationPtr Evaluation;
    IGraphicsPtr Graphics;
    IPresentationPtr Presentation;

    // Wrapper methods for error-handling

    HRESULT New ( );
    HRESULT LoadNet (
        _bstr_t NetPath,
        VARIANT_BOOL Additive );
    HRESULT SaveNet ( );
    HRESULT SaveNetAs (
        _bstr_t NetPath );
    HRESULT LoadLayout (
        _bstr_t LayoutPath );
    HRESULT SaveLayout (
        _bstr_t LayoutPath );
    HRESULT ImportANM (
        _bstr_t NetPath,
        _bstr_t RoutesPath,
        _bstr_t InputPath,
        ImportType ImportType,
        int importOptions,
        int evaluationInterval );
    HRESULT BringToFront ( );
    HRESULT Exit ( );
    INetPtr GetNet ( );
    ISimulationPtr GetSimulation ( );
    IEvaluationPtr GetEvaluation ( );
    IGraphicsPtr GetGraphics ( );
    HRESULT ImportSynchro (
        _bstr_t synchroFile,
        _bstr_t workingDirectory,
        VARIANT_BOOL adaptiveImport );
    IPresentationPtr GetPresentation ( );
    HRESULT ExportVisum (
        _bstr_t NetPath,
        VisumExportType ExportType );
    HRESULT ImportResults (
        _bstr_t Path );
    HRESULT VissimTest (
        int TestNo,
        _bstr_t Param1,
        _bstr_t Param2,
        _bstr_t Param3 );
    HRESULT SuspendUpdateGUI ( );
    HRESULT ResumeUpdateGUI (
        VARIANT_BOOL enforceRedraw );

    // Raw methods provided by interface

      virtual HRESULT __stdcall raw_New ( ) = 0;
      virtual HRESULT __stdcall raw_LoadNet (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ VARIANT_BOOL Additive ) = 0;
      virtual HRESULT __stdcall raw_SaveNet ( ) = 0;
      virtual HRESULT __stdcall raw_SaveNetAs (
        /*[in]*/ BSTR NetPath ) = 0;
      virtual HRESULT __stdcall raw_LoadLayout (
        /*[in]*/ BSTR LayoutPath ) = 0;
      virtual HRESULT __stdcall raw_SaveLayout (
        /*[in]*/ BSTR LayoutPath ) = 0;
      virtual HRESULT __stdcall raw_ImportANM (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ BSTR RoutesPath,
        /*[in]*/ BSTR InputPath,
        /*[in]*/ ImportType ImportType,
        /*[in]*/ int importOptions,
        /*[in]*/ int evaluationInterval ) = 0;
      virtual HRESULT __stdcall raw_BringToFront ( ) = 0;
      virtual HRESULT __stdcall raw_Exit ( ) = 0;
      virtual HRESULT __stdcall get_Net (
        /*[out,retval]*/ struct INet * * Net ) = 0;
      virtual HRESULT __stdcall get_Simulation (
        /*[out,retval]*/ struct ISimulation * * Simulation ) = 0;
      virtual HRESULT __stdcall get_Evaluation (
        /*[out,retval]*/ struct IEvaluation * * Evaluation ) = 0;
      virtual HRESULT __stdcall get_Graphics (
        /*[out,retval]*/ struct IGraphics * * Graphics ) = 0;
      virtual HRESULT __stdcall raw_ImportSynchro (
        /*[in]*/ BSTR synchroFile,
        /*[in]*/ BSTR workingDirectory,
        /*[in]*/ VARIANT_BOOL adaptiveImport ) = 0;
      virtual HRESULT __stdcall get_Presentation (
        /*[out,retval]*/ struct IPresentation * * Presentation ) = 0;
      virtual HRESULT __stdcall raw_ExportVisum (
        /*[in]*/ BSTR NetPath,
        /*[in]*/ VisumExportType ExportType ) = 0;
      virtual HRESULT __stdcall raw_ImportResults (
        /*[in]*/ BSTR Path ) = 0;
      virtual HRESULT __stdcall raw_VissimTest (
        /*[in]*/ int TestNo,
        /*[in]*/ BSTR Param1,
        /*[in]*/ BSTR Param2,
        /*[in]*/ BSTR Param3 ) = 0;
      virtual HRESULT __stdcall raw_SuspendUpdateGUI ( ) = 0;
      virtual HRESULT __stdcall raw_ResumeUpdateGUI (
        /*[in]*/ VARIANT_BOOL enforceRedraw ) = 0;

In addition to invoking Vissim as an automation server,  In-Menu/Event-based COM scripting has a different mechanism.

In the In-Menu/Event-based COM script,  there is no explicit instantiation of IVissim. As a matter of fact,  there is a “Vissim” object already created, ready to be referenced in the script.

That is a mystery, isn’t?

To trace how and when “Vissim” object is created in the scripting context, we need to trace the life cycle of  the class CCOMVissim. That is the key to the original question – i.e.,  how to call all those COM functions inside an external DLL.

We’ll continue with our journey looking into the life cycle of the class CCOMVissim.  Right now, please just look at IVissim declaration again, and remember the following:

IVissim declaration stipulates nothing but just a memory blueprint. The sequence of all its virtual members are the slots of the v-table of IVissim’s implementation class.  This, is the “Open Sesame”.

Dissecting Vissim COM Internal from Inside Out (1)

There was an interesting discussion at PTV Vissim LinkedIn group – how to access Vissim COM interface inside a DLL, e.g., a Signal Control DLL,  an External Driver DLL etc.  To properly answer this question, some in-depth understanding of the COM technology,  C++ compiler internals, and Vissim binary level details are in order.

To begin with, Component Object Model (COM) is just a binary-level coding standard for out-of-process and in-process communication. It’s been out there for many years but somehow never become popular due to its daunting learning-curve for ordinary programmers,  and then Microsoft began promoting .NET, which is essentially similar idea revamped at the level of Common Language Run-time (CLR) and Intermediate Language (IL).

In the nostalgia good-old days,  COM/C++ programming required too steep learning curve to weed out sub-par programmers.  Nowadays programming is so much easier with various .NET languages or scripting languages that do not require low-level knowledge of hardware or compiler internals. The barrier to programing is quite low nowadays; anyone with common  sense can pick up programming,  develop some apps, and sell such on streets.

In the context of Vissim,  PTV wraps up the simulation elements and workflow into various interfaces. These interfaces are implemented (in C++) at binary level thus any language that supports COM (by their respective compilers) will be able to use Vissim’s COM interface to interact with Vissim functionality.

In the  earlier days of Vissim, its COM interfaces allow a client application to invoke Vissim as an automation server (as an out-of-process use case). Then PTV added In-Menu scripting, that supports invoking COM inside the active Vissim instance, using Python, VBS, or JS.

Starting Vissim 6, PTV completely refactored and redesigned Vissim, almost rebuild the software from scratch, inside out.  As part of this process, more gems are added,  one of such, is the so-called “event-based” COM scripting. “Event-based” COM scripting is a use case of in-process COM; it was added since Vissim v7.

Once again, with the In-Menu COM/Event-based Scripting,  and many other new designs/architectures, Vissim has set up a solid foundation significantly better than its v5 and any earlier generations, making itself readily primed for the future. A big congratulation is due to the PTV development team for this achievement, seriously.

Some of my earlier post discussed Vissim COM Internal as well.

As of today, Vissim 7-09 appears as the most impressive redemption of a legacy software (I mean, particularly, Vissim v4 and earlier versions) – and presents itself, with so many improvements and beef-ups, and as a powerful, sleek and increasingly popular tool for its users that have been yelling and crying for  years while its competitors eating up its market share.

Aside from COM interface, Vissim also provides various APIs e.g., Signal Control API, Emission API, External Driver API etc. These APIs have to be compiled in DLL to be loaded by Vissim host, which calls back the exported functions when certain events fire.

It is interesting that “event-based” COM scripting is capable of providing a unified interface for all the above APIs.  In future, it is possible that PTV might gradually phase out all these DLL-based APIs so everything is done through a unified event-based COM scripting. Granted, that is just my personal perspective.

Now, coming back to the million dollar question –  can we access COM interface from inside an API DLL? For example,  from inside External Driver DLL,  how can we access some, if not all of the COM functions?

The answer is: yes,  that is doable, but with some twist.

Now you start to have a faint of heart,  aren’t you?  Before we roll up our sleeves and jump to the 1-2-3 steps, I want you to take a look at the following snapshots – they are the key to the solution.

The following are the 58 exported functions from comsrv.dll, which is located in Vissim installation Exe folder. Most of these exported functions, are class methods of several classes, primarily:

  • CComVissim
  • CComNetObjHelper
  • CComVehicleContainer
  • CComSignalController
  • CComPedestrianContainer
  • CComException

💡 comsrv.dll is the “hub” of all Vissim COM functionality.

With the above in mind,   let me lead you to the interesting journey to figure out comsvr.dll  and Vissim COM invocation flow, till we reach the final solution to the original question.




(to be continued)

VMWare USB Passthrough: Running Vissim in a Virtual Machine

I bet it is not uncommon for someone to have a faint of heart at the idea of using VISSIM in a virtualized environment:

Using a virtual machine, it becomes easier and more orderly to debug and test various COM client applications, customized API DLLs and such, without messing around ordinary simulation projects . On the other hand, using a second virtual machine dedicated to traffic simulation models,  the project portfolio is organized and streamlined, while the IT administration load is simplified since a uniform work space is maintained between different modelers.

The following shows two snapshots of Vissim running inside a VMware 11.1.0 virtual machine.  In them, the Vissim instance was running smooth like a charm, without tangible performance hit, even running a 3D animation.


VISSSIM 3D Animation in Virtual Machine


VISSIM 2D Animation in Virtual Machine

In the above example, the hardware specification of the running computer is:


  • WIN7x64
  • Intel i7-3920XM Quad Core@2.90GHz/3.1GHz
  • 32GB RAM(large host RAM will prevent frequent memory swapping)
  • Samsung 850 Pro SSD 1TB (SSD makes a big difference)


  • OS:Windows Server 2012 R2;
  • RAM: 8GB;
  • CPU: Enable the option “Virtualize Intel -VTx/EPT or AMD-V/RVI;
    • If the physical processor is enabled with EPT, this would give near native performance;
  • Graphic 3D and Graphic Memory setting as follows:

Virtual Machine Graphics Setting

The following is useful tips for improving Guest performance.

Add the following 3 lines in C:\ProgramData\VMware\VMware Workstation\settings.ini;

  • mainMem.useNamedFile = “FALSE”

This would disable the on-disk memory-swap file *.vmem, while forcing the virtual memory to be backed up by the host swap space. This means, if the host has enough physical RAM (e.g., 32GB),  all nominal guest-RAM will be allocated in host-memory hence improves performance.

  • MemTrimRate = “0”

This would disable memory page trimming. Memory trimming will return unused virtual machine memory to the host machine. By disabling such, the I/O is saved and will improve performance especially if the host is short of RAM.

  • scsi0:0.virtualSSD =  1

This is to explicitly let Guest OS know the virtual disk is SSD.

In order for the guest OS to see the hardware dongle,  the so-called USB Passthrough feature of VMWare is needed.  Of course, if the license is a network one, then this is a non issue – as long as the CodeMeter license server is configured , and the guest OS’ firewall set up properly.

To use USB Passthrough feature of VMWare, make sure the following services are enabled, or alternatively, make sure they are not disabled (See following figure) 💡 :

  • VMware Authorization Service
  • VMware USB Arbitration Service



VMware Servivces Required for USB Passthrough

With the USB dongle plugged in the host’s USB port,  let go the “passthrough” by checking the “WIBU-Systems CodeMeter-Stick”, under VM->Removable Device.


Connect the “Passthrough” CodeMeter Key in Virtual Machine

1 2 3 6