Tuesday, October 21, 2008

Option Strict On causes Disallows Late Binding Error when getting Variant Array from a COM Object

I have several ActiveX controls that I use with .NET. Generally, there are not too many problems using them with .NET, but I have come across one error that was difficult (for me) to solve.

Since the ActiveX controls were originally written for VB6, they return Variants and arrays are returned as Variants of Variants. This is all fine because .NET has an Object type to work with the variants. As a rule, however, I use Option Strict On because if you don't use this option, Dotfuscator will really cause problems without letting you know in advance. But the catch is that with Option Strict on, you cannot do something like the following:

Dim varArray as Object
Dim count as Integer

SomeComObject.GetList( varArray, count )

For i as Integer = 0 to count - 1

Debug.WriteLine( varArray(i).ToString )


varArray will return list of integers, but as a Variant Array of Variant Integer values.

The code above will not work with Option Strict On because the varArray(i) is late bound and this is not allowed. My first though was to try:

Dim val as integer = CType( varArray(i), Integer)

The above code does not work or any similar cast.

The only solution I have discovered (and there are probably others) is to cast the Variant array as an Object array like:

Dim vArray() as Object = CType( varArray, Object())

Then the vArray is a Object Array and can be further cast to other types without catching on the Option Strict On. For example:

Dim catList As Object = Nothing
Dim offsetList As Object = Nothing
Dim filterList As Object = Nothing

While viewObj.GetElementsInRangeFetch(1000, catList, offsetList, filterList, blockCount)

Dim cList() As Object = CType(catList, Object())
Dim oList() As Object = CType(offsetList, Object())
Dim fList() As Object = CType(filterList, Object())

For j As Integer = 0 To blockCount - 1
ProcessFeature(CInt(cList(j)), CInt(oList(j)), CInt(fList(j)))

catList = Nothing
offsetList = Nothing
filterList = Nothing

End While

This may not be the cleanest solution, but it does work and allow the Option Strict setting to be left on.

No comments: