title: Return Array from C# COM Library to VBA
body: <p>I've spent quite some time trying to find a solution but I just can't seem to get it to work. The situation is as follows:</p>
  
  <p>I'm setting up a c# com library to be used by a vba macro. The c# library method in question takes two arrays as parameters and returns an array identical in size and type to the first parameter. Here's the c# code (Interface and implementation):</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Runtime.InteropServices;
  using System.Reflection;
  using System.Windows.Forms;
  
  namespace Aufbereiten.Base.Controller
  {
      [Guid("A341A58B-96CA-42B8-8256-B8AC16586176")]
      public interface IExposer
      {
          [DispId(1)]
          void Connect(String macroName, String inputFileName, String functionType);
          [DispId(2)]
          Boolean Run();
          [DispId(3)]
          object[] StringCleaner(object lineOut, object headerOut);
      }
  
      [Guid("C66FF152-60E2-4AF3-9D65-655C224A241E")]
      [Serializable(), ClassInterface(ClassInterfaceType.None), ComVisible(true)]
      public class Library : IExposer
      {
          #region Fields
          private MainController _mc;
          #endregion
  
          #region Properties
          public MainController MC
          {
              get { return _mc; }
              set { _mc = value; }
          }
          #endregion
  
          #region Methods
          public void Connect(String macroName, String fileName, String functionType)
          {
              MC = new MainController(macroName, fileName, functionType);
          }
  
          public Boolean Run()
          {
              return MC.Run();
          }
  
          /// &lt;summary&gt;
          /// Cleans input string of unwanted characters
          /// &lt;/summary&gt;
          /// &lt;param name="lineOut"&gt;String Array&lt;/param&gt;
          /// &lt;param name="headerOut"&gt;Integer Array&lt;/param&gt;
          /// &lt;returns&gt;String array&lt;/returns&gt;
          public object[] StringCleaner(object lineOut, object headerOut)
          {
              // Convert input objects to List and convert return List to string array directly
              return MC.Generic.StringCleaner(ComObjectToStringList(lineOut), ComObjectToIntList(headerOut)).ToArray&lt;string&gt;();
          }
  
          /// &lt;susgbomary&gt;
          /// Converts a com object into a string list
          /// &lt;/summary&gt;
          /// &lt;param name="comObj"&gt;object&lt;/param&gt;
          /// &lt;returns&gt;String list&lt;/returns&gt;
          private List&lt;string&gt; ComObjectToStringList(object comObj)
          {
              List&lt;string&gt; result = new List&lt;string&gt;();
  
              // Convert COM object (VBA array) to string list
              Type comObjType = comObj.GetType();
  
              object[] args = new object[1];
              int numEntries = (int)comObjType.InvokeMember("Length", BindingFlags.GetProperty, null, comObj, null);
              for (int i = 0; i &lt; numEntries; i++)
              {
                  args[0] = i;
                  string currentEntry = (string)comObjType.InvokeMember("GetValue", BindingFlags.InvokeMethod, null, comObj, args);
                  if (currentEntry == null)
                  {
                      result.Add("");
                  }
                  else
                  {
                      result.Add(currentEntry);
                  }
              }
  
              return result;
          }
  
          /// &lt;summary&gt;
          /// Converts a com object into an int list
          /// &lt;/summary&gt;
          /// &lt;param name="comObj"&gt;object&lt;/param&gt;
          /// &lt;returns&gt;Int32 list&lt;/returns&gt;
          private List&lt;int&gt; ComObjectToIntList(object comObj)
          {
              List&lt;int&gt; result = new List&lt;int&gt;();
  
              // Convert COM object (VBA array) to int list
              Type comObjType = comObj.GetType();
  
              object[] args = new object[1];
              int numEntries = (int)comObjType.InvokeMember("Length", BindingFlags.GetProperty, null, comObj, null);
              for (int i = 0; i &lt; numEntries; i++)
              {
                  args[0] = i;
                  result.Add((int)comObjType.InvokeMember("GetValue", BindingFlags.InvokeMethod, null, comObj, args));
              }
  
              return result;
          }
          #endregion
      }
  }
  </code></pre>
  
  <p>The Generic.StringCleaner method will do the actual work of cleaning the parameter array "lineOut" of unwanted characters. The following is an extract of the VBA code calling the library method:</p>
  
  <pre><code>Dim arrLineOut() As Variant
  Dim dicInToOut As New Scripting.Dictionary
  
  ...
  
  Dim lib As New Aufbereiten.library
  lib.Connect ThisWorkbook.Name, "_Library_Test_custFile.xlsx", "CustImport"
  arrLineOut = lib.StringCleaner(arrLineOut, dicInToOut.Items)
  </code></pre>
  
  <p><strong>All the operations inside the c# run flawlessly except the returning of the result, the cleaned array.</strong></p>
  
  <p>When I run the macro I get a </p>
  
  <blockquote>
    <p>runtime error 80131533: A mismatch has occurred between the runtime type of the array and the sub type recorded in the metadata.</p>
  </blockquote>
  
  <p>Could anyone please enlighten me what I'm doing wrong here?</p>