views:

51

answers:

2

I have a COM object written in Visual Fox Pro 9.0. It has the following procedure:

    PROCEDURE GetArray(m.vcArrayName as String) as array
RETURN @&vcArrayName

The COM object is referenced in a VS2010 project using C#. The signature of the procedure in C# is:

object GetArray(string vcArrayName);

When debugging I can see that the returned value is {object[1..1]} while the type is object {object[]}. Expanding the variable, I can see that it is an array of base 1 with one element which is an empty string ("");

However, I can not cast this value to object[]. I always get an InvalidCastException with a Norwegian message saying that I can't cast Object[*] to Object[].

A strange thing is that if the COM object returns a two dimensional array I have no problem casting it to object[,]. I find it very strange that two dimensions are easier to deal with than one!

The question I'd like answered is:

What is this Object[*] business? Can anybody tell me if it is a bad translation in the Norwegian exception message or if Object[*] is some kind of obscure C# syntax that I haven't heard of?

+2  A: 

object[] is a vector in CLI terms; these must be 0-based and 1-dimensional. object[*] is an array that happens to be 1-dimensional, and may even (although not in your case) even be 0-based. But it isn't a vector.

Rather than casting, you're going to have to copy the data out into an object[]. I made the same mistake here.

You should be able to use CopyTo:

array.CopyTo(vector, 0);

(where array is the object[*] and vector is the object[])

Marc Gravell
+3  A: 

You are getting a multi-dimensional array with a dimension of 1 instead of a vector. The C# language doesn't allow you to declare an array like that. You can reference the return value with the Array class, which allows conversion with code similar to this:

public static object[] ConvertFoxArray(Array arr) {
  if (arr.Rank != 1) throw new ArgumentException();
  object[] retval = new object[arr.GetLength(0)];
  for (int ix = arr.GetLowerBound(0); ix <= arr.GetUpperBound(0); ++ix)
    retval[ix - arr.GetLowerBound(0)] = arr.GetValue(ix);
  return retval;
}
Hans Passant