I\'m currently in the unfortunate position of having to call a VBA macro from C#, via the COM Interop. The macro returns an array of strings and looks something like:
Your code was
var result = (string[])xlApp.Run("Foo", ... missing args ...);
As you have pointed out there is different behaviour with a 1-based array, with a zero-based array in VB your code does work.
You can get at the data like this
var result = (Array)xlApp.Run("Foo", ... missing args ...);
var stringsResult = result.Cast<string>[];
This gives you an IEnumerable of string
.NET supports such arrays (that have lower bound different from 0), you can create one using such snippet:
Array arr = Array.CreateInstance(typeof(string), new int[] { 5 }, new int[] {1});
The simplest way to convert such array to string[] is (although, it's copying data, on the other hands, those are just references, so if your arrays aren't too long, you won't get huge perf hit):
string[] x = new string[5];
Array.Copy(arr, 1, x, 0, 5);
Edit: Or using more general approach:
string[] x = new string[arr.GetLength(0)];
Array.Copy(arr, arr.GetLowerBound(0), x, 0, arr.GetLength(0));
Edit2: It also looks like casting arrays with lowerbounds != 0 works for fine, if there are more than 1 dimension, you can read more here, where Jon Skeet seems to answer why that happens.
Edit3: To make response less ambiguous, following djna's comments. This is how you could obtain string[] out of object returned by a method, that can't be cast to string[] directly, because it has lowerBound != 0:
Array arr = (Array)xlApp.Run("Foo", ... missing args ...); //Here I assume that .Run() method is returning object, or something that has to be casted to Array.
string[] result = new string[arr.GetLength(0)];
Array.Copy(arr, arr.GetLowerBound(0), result, 0, arr.GetLength(0)); // Here data is copied, but only references in this scenario