Previous | Index | Next 

[HOWTO] Expose arrays with nonzero lower index to COM clients

If you are migrating a DLL that must continue to serve one or more COM clients, it might happen that one of your methods must return an array with a nonzero lower bound, which aren’t supported natively by either VB.NET and C#. This article illustrates a workaround. Let’s start with the following VB6 method:

    Public Function Models() As String()
	    Dim arResult(1 To 2) As String
	    arResult(1) = "Ford Escort"
	    arResult(2) = "Volkswagen Touran"
	    Models = arResult
    End Function

Here’s how the method should look in .NET to work correctly:

    Imports System.Runtime.InteropServices
    Public Function Models() As  Array
	    Dim arResult(2) As String
	    arResult(1) = "Ford Escort"
	    arResult(2) = "Volkswagen Touran"
	    Return manageLowerBound(arResult)
    End Function

    Private Function manageLowerBound(ByVal oldArray() As String) As Array
	    Dim lowerBounds As Int32() = {1}
	    Dim lengths As Int32() = {oldArray.GetUpperBound(0)}
	    Dim oneBasedArray As Array = Array.CreateInstance(GetType(String),
                    lengths, lowerBounds)
	    For i As Integer = oneBasedArray.GetLowerBound(0) To oneBasedArray.GetUpperBound(0)
		    oneBasedArray(i) = oldArray(i)
	    Return oneBasedArray
    End Function

    // C#
    ising System.Runtime.InteropServices;

    public [return: MarshalAs(UnmanagedType.SafeArray, _
 	    SafeArraySubType=VarEnum.VT_BSTR)] Array Models()System.Array
	    string[] arResult = new string[3];
	    arResult[1] = "Ford Escort";
	    arResult[2] = "Volkswagen Touran";
	    return manageLowerBound(arResult);

    private Array manageLowerBound(string[] oldArray)
	    int[] lowerBounds = new int[]{1};
	    int[] lengths = new int[]{oldArray.GetUpperBound(0)};
	    Array oneBasedArray = Array.CreateInstance(typeof(String), lengths, lowerBounds);
	    for (int i = oneBasedArray.GetLowerBound(0); i <= oneBasedArray.GetUpperBound(0); i++)
		    oneBasedArray[i] = oldArray[i];
	    return oneBasedArray;




Previous | Index | Next