Application & Data Migration Blog Posts | Mobilize.Net

VBUC 6.3 syntactic optimizations

Written by John Browne | Apr 2, 2015 9: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.
Default values for enums are the result of applying the rules previously described to the literal ‘0’.

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.