VBUC 6.3 syntactic optimizations
by John Browne, on Apr 2, 2015 2:55:06 PM
Note: the following is courtesy of Hugo Fernandez, who is responsible for much of the recent improvements in the VBUC. I asked Hugo for some specific improvements made to the tool in order to reduce subsequent compile errors after migration. These are a few examples; we'll post more shortly.
FixedLengthString in Structures
Now all cases get converted to an equivalent combination of a char[size] field and a public string property, plus the MarshalAs attributes to provide the interoperability functional equivalence.
VB6
Public Type MyStruct Buffer As String * 364 End Type
C#
public struct MyStruct { [InteropServices.MarshalAs(InteropServices.UnmanagedType.ByValArray, SizeConst=364)] private char[] _Buffer; public string Buffer { get { return new string(_Buffer); } set { MemoryHelper.CopyValueToArray(_Buffer, value); } } public static MyStruct CreateInstance() { MyStruct result = new MyStruct (); result._Buffer = new char[364]; return result; } }
Default Values and Constants
The handling of many default values was improved to provide the same behavior as in VB6 as well as avoid compile errors when constants are expected.
Examples:
Consts:
When a constant cannot be provided (e.g.: default value of DateTime), features requiring constants are avoided:
Public Sub Foo(Optional ByVal vdtFilterDate As Date = 0)
Is converted to: the following C# with overloading:
public object Find(System.DateTime vdtFilterDate) { // Converted Code } public object Find() { return Find(DateTime.FromOADate(0), 0, 0, "N"); }
Colors:
- Color c = -1 is converted to Color c = Color.Empty
- All default values of color, with OLE_Color, ColorConstants or SystemColorConstants are now converted to System.Color.Black.
Enumerates, Coercions, and Default Values:
When a literal integer is assigned or compared to an enum it will be converted as follows:
- If there is an element in the enum with that value, that element is converted instead of the literal.
- Otherwise a casting to the enum is generated.
Windows APIs / PInvoke
Compilation errors where fixed by improving the way duplicated Windows APIs are merged into a unique project. Multiple Windows API declarations, usually inconsistent ones, can be found in VB6 applications. The VBUC 6.3 analyzes and consolidates them in a unique project where declarations are merged with an enhanced process avoiding lots of compilation errors. Also, structures that are used directly or indirectly by the Windows APIs are also moved and consolidated.
VB6
Declare Function FuncName Lib "LibName.dll" (struct as MyStruct, var as Integer) As Integer // In a different file Declare Function FuncName Lib "LibName.dll" (struct as MyStruct, var as String) As Integer Type MyStruct otherStruct as MySecondStruct End Type Type MySecondStruct … End Type
C#
- All the declarations are moved to a consolidated project.
- A unique declaration is created for FuncName
- The invocation of the primitive parameter is made through IntPtr, making the necessary adjustments (marshaling, memory copying, unmanaged code) in the specialized project, hidden from the rest of the application logic.
- Both structures (the ones used directly and the one used indirectly) are also moved to this specialized project.
- All the references to the original FuncName method, and the structs are qualified to reference them into the new project.