Image Map of Navigational Panel to Home / Contents / Search Parsing Expressions of Interest

Part IV : The Quick Brown Parser Jumps Over To VB4

Image of line

Generating a function library works pretty nicely for VB3. It is, after all, the way to produce portable code. However, one of the great things about VB4 is that you can take a reasonable library and make it even more useful by wrapping the whole thing up as an OLE server. This is great for convenience. All you have to carry around is the DLL, and you know you can upgrade it independently, so long as it is backward compatible. It's a great way to introduce standard code modules to a range of projects, just make them available to all the project teams as a collection of DLLs (preferably on a network server, so that upgrading can be done centrally).

Because it might actually be useful, and because it serves as a reasonable example of how to do this very simply, I decided to port the expression parser and token library to an OLE server. And it's really not difficult. Keep in mind I moved the code to VB4 with minimal changes to demonstrate how simply it could be done. Therefore there are some areas where the code could be improved by using some of VB4's features, and this has not been done.

Cheating even further I exposed the calculation library and the token library as one OLE object, again to achieve the OLE port with maximum simplicity (arguably laziness).

The libraries themselves stay the same, excluding the API calls - used to write the tokens in the token library to an INI file and to read them back. I simply inserted VB4 compiler directives to use either the 16 or 32 bit APIs depending on the platform being used.

I added a BAS file called ExpressionParserMain.bas, and included a Sub Main with no code. This was because we don't want to display any forms, therefore Sub Main must be selected as the Startup form in the Project options. This can again be used for initialisation code as required. I also changed the startmode to 'OLE Server' in the Project options dialog. In the Advanced section of this dialog I set 'Use OLE DLL Restrictions' to true. This allows the effective debugging of the OLE server using two copies of VB4. One which runs the OLE server, the other running an OLE client. This actually works really neatly.

Going to the Insert menu I selected Class Module. This creates a class module that defines the class that the OLE server will allow clients to create object instances of (still following me?). The class module has three properties, all of which are of some importance. Its Instancing property must be set to 'Creatable MultiUse'. This is a requirement of classes that are to be exposed by OLE servers. Secondly, the class must be given a Name. This is important, when an application wants to create an object of the class you are exposing, they use the call CreateObject('ServerName.ClassName'). This is not the only way to create the object, but it demonstrates the use of the class' Name property. The class must also be made available to outside applications by setting its Public property to true.

Next we write the contents of the class module. In this case all the code that will do the actual work of the Class has been written (in the parser and token libraries). Therefore all we need to write is the methods and properties that provide the OLE interface to the functions we want to expose. Most of the library functions are reasonably simple calls anyway, so this is not very difficult. For instance, to provide a method that evaluates a simple expression (using the simplest version of the parser, written in Part I) we simply wrap the call in a Function that is exposed by the class as a method. Here is the code:

  Public Function ExpressionSimple(ByVal sSimple As String) As String
    Dim sResult As String
   
    ' Parse the simple expression through the simple
    ' expression handler.
    sResult = CalculationLib.SimpleExpressionEvaluate(sSimple)
    ExpressionSimple = sResult
  End Function

The OLE client would execute this method like so:

  Dim objParser as Object
  Set objParser = CreateObject('Expression.Parser')
  MsgBox objParser.ExpressionSimple('6*7'), 64, "Answer to 6*7"

Virtually all the code is that simple. To declare a method that does not return a value you simply declare it as a Sub, instead of a Function. Like this:

  Public Sub ClearTokens()
    ' Redirect to Lib function.
    TokenLib.ClearTokens
  End Sub

To call the same:

  objParser.ClearTokens

To define any properties we want to expose, we write a Property Let procedure to allow the OLE client to set that property, and a Property Get procedure to allow the client to retrieve that property. The beauty of this is that you can execute whatever code you need - to either calculate a value to retrieve, or to act upon the value being set. These are pretty well dealt with in the VB4 manuals if you want an in depth explanation, but here is an example from the OLE server we are building:

  Property Get TokenCount() As Long
    TokenCount = TokenLib.GetTokenCount()
  End Property

In code this is referenced just like a property of any other object.

  Label1.Caption = "There are " & CStr(objParser.TokenCount) 
                   & " Tokens defined."

Once we have written these simple wrapper functions and Property Let/Get procedures we have a class ready to be exposed. We also have the underlying code already written, all that needs to be done is to compile the project using File|Make OLE DLL File…

Creating a useful OLE server, as you can see, is not so daunting as it might at first seem. In this case the object model is somewhat imperfect, it would be nice to expose the Token library as a separate class for example, but once you are comfortable with creating OLE servers those sort of structural changes happen somewhat more readily. The challenge in moving to VB4 is to make use of its new features, not just write code the same way we did in VB3. The proper use of classes and OLE servers is arguably one of the most important changes we can make to the way we do things. You know, cure the world of all known disease with OOP. I hope this has helped serve as a useful example for those of you wondering what all this VB4 class/OLE server stuff is about.

The zip file available for download (22kb) has the VB3 code and the VB4 project for the OLE server, as well as a compiled 32-bit OLE server.

And that's all I have to say, goodbye!


Image of arrow to previous article

Image of line

[HOME] [TABLE OF CONTENTS] [SEARCH]