Linker IT Software
Google
Web www.oraxcel.com
menubar-top-links menubar-top-rechts
Home Help Search Login
Welcome, Guest. Please Login.
SQL*XL: Database to Excel bridge litLIB: Excel power functions pack ExcelLock: Locking and securing your valuable Excel spreadsheets encOffice: Protect your Excel file easy and safe encOffice: Protect your Excel file easy and safe
Pages: 1
Solving the dll versioning problem in classic VB (Read 5477 times)
Gerrit-Jan Linker
YaBB Administrator
*****




Posts: 75
Solving the dll versioning problem in classic VB
30.12.07 at 11:35:40
 
Solving the dll versioning problem in classic VB
 
The problem:
In classic VB - Visual Basic 5 or 6 - there is a dll versioning problem. ActiveX dlls can be written using VB and these dlls can be used by many executable programs - at least that is the idea. The problem exhibits itself when making an update to the dll. Compiling the dll it quite often no longer works well with all executable programs that use it even if care has been taken to keep the dll backwards compatible.
 
When using an ActiveX dll a programmer will include the dll as a reference to his project. Visual basic will add the dll to the project configuration storing the so called GUID - a long unique signature - in the vb source. It is exactly here where the problem is. Visual basic assigns a new GUID almost any time to the dll project when it is compiled. This cause all executable programs to not recognise it anymore as they are still coded to look for the old GUID. The file has been overwritten with the new version of the dll - with a new and unrecognised GUID by the executable programs.
 
This leads to what most people experience as the inability of classic VB to be facilitate the building of libraries of useful ActiveX dlls. Suppose you have written a dll with functionality that is shared by say 10 executable programs. For each update of the dll you must recompile all executables and distribute them. If you have a customer that has purchased 2 of your software programs and he updates only one it will leave the second software dead in the water as it does not recognise the GUID of the new version of the dll.
 
My solution:
I found a way around this by mixing the use of static and dynamic binding of dlls and the use of conditional compilation. The solution of using late or dynamic binding is usually not favoured by programmers. It will cause the intellisense feature of VB to not work which hampers the efficient writing of VB code. Technically late binding is not preferred as it is said to be slower however I have never experienced problems with this. If you don't principally object to use late binding this is how it works.
 
In static binding you will add a reference to the VB project to the dll. Suppose the ActiveX dll project is named MyDLLProject and that it contains a class called MyClass. To create a new instance of that class you can write this code:
 
Dim obj as MyDLLProject.MyClass
Set obj = New MyDLLProject.MyClass

 
When using late binding this code will become (and this will work always when the above code for static binding is working):
 
Dim obj as Object
Set obj = CreateObject("MyDLLProject.MyClass")

 
Irrespective of the method of binding you use you can now further use the obj object in your code. There is one very irritating problem to a programmer when using late binding however. This is the inability to use the VB intellisense feature that essentially displays all the API syntax for using the class in various ways when coding the VB code.  
 
I found a workaround that will not break intellisense and that mixes the use of static and dynamic binding. In my solution I use static binding when I am writing the code so I can use intellisense. I will use late binding when I have compiled my executable and have built my distribution files.
 
To start with I am using the normal technique of static binding - adding a reference to my project of the dll I am going to use. Usually I write the dll at the same time of writing the front-end executable and then I find the use of bundeling more than one project (vbp) into a project group (vbg) quite handy. This is not essential to my proposed solution for getting around the dll versioning problem however.
Once I have written the code I am introducing a project variable. You can add one in the project properties in the make section. I usually add a variable called testing and set the value to 1. So I add: testing = 1. In the code I can use this value to write some conditional compilation statements in which I can switch between static and late binding. When the testing variable is set I want to use static binding. This is what I will use when writing the software. When the testing variable is not set I want to use late binding. This is what I will use at runtime so I can bypass the dll versioning problem.
 
The code I wrote above for late and static binding to use my dll will now become:
 
#if testing then
  Dim obj as MyDLLProject.MyClass
  Set obj = New MyDLLProject.MyClass
#else
  Dim obj as Object
  Set obj = CreateObject("MyDLLProject.MyClass")
#end if

 
I hope you will agree that this code will only slightly make the VB code less clear to read and it is slightly inconvenient to have to write these statements. I will give you something back however. You do not need to update every single executable program that uses the dll as long as you have written the executable using the technique above - with using late binding at runtime.
 
Are there any drawbacks to the technique described above? Unfortunately there is one drawback I have found so far. First an inconvenience. I find that the code will become less clear when passing objects to subroutines. Using the conditional compilation code subroutine calls will need to be coded like this:
 
#if testing then
Sub MySub( obj as MyDLLProject.MyClass)
#else
Sub MySub(obj as Object)
#end if
Back to top
 
« Last Edit: 30.12.07 at 11:38:32 by Gerrit-Jan Linker »  

Gerrit-Jan Linker
Linker IT Software
Email WWW Gerrit-Jan Linker   IP Logged
Gerrit-Jan Linker
YaBB Administrator
*****




Posts: 75
Re: Solving the dll versioning problem in classic
Reply #1 - 30.12.07 at 11:39:44
 
The drawback I have found when using the described technique is that with late binding no named enums can be used. Suppose I have defined an enum in my dll project as:
 
Public Enum MyEnum
  One = 1
  Two = 2
End Enum

 
In my executable program, having a statically linked ActiveX dll linked, I can use this enum in code like this:
 
Dim lngChoice as Long
lngChoice = MyDLLProject.MyEnum.One

 
When using late binding this cannot be used anymore. We will be forced to use:
 
Dim lngChoice as Long
lngChoice = 1

 
Of course this can also be fixed using conditional compilation. It discourages me however from using enums however.
 
Conclusion:
My conclusion is that with the technique described above classic Visual Basic - VB5 and VB6 - can be used to write libraries of dlls with reusable code without having to worry about the versioning problems. One thing that you should have to do yourself is ensuring your code is backwards compatible. You must ensure that the new dll being called by the old executables still exhibits itself in the same way as before. If you change the behavior of the dll the executable programs will obviously fail. This is the origin of the reason why VB creates a new GUID. Every time the signature (public methods an properties) of a class changes the GUID will be changed to a new one. It does not make sense however when you just add new code to the project. Care should be taken when changing the existing code of classes.
Back to top
 
 

Gerrit-Jan Linker
Linker IT Software
Email WWW Gerrit-Jan Linker   IP Logged
Pages: 1