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.
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.
Public Type MyStruct Buffer As String * 364 End Type
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; } }
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.
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"); }
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.
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