title: Passing C# array by ref into C++ DLLImport method trims values
body: <p>I am making a DLL wrapper for some C++ code and have run into an issue. It will be easier for me to illustrate my problem after providing some sample code.</p>
  
  <p>In my C++ application's .h file:</p>
  
  <pre><code>#pragma once
  namespace Wrapper {
  extern __declspec(dllexport)
      void SANDBOX(int arrayLength, int* intArray);
  }
  </code></pre>
  
  <p>In my C++ application's .cpp file:</p>
  
  <pre><code>#include "stdafx.h"
  #include "Wrapper.h"
  #include &lt;windows.h&gt;
  using namespace Wrapper;
  
  extern "C"{
  
      BOOL APIENTRY DllMain( 
                              HANDLE hModule,
                              DWORD  ul_reason_for_call,
                              LPVOID lpReserved )
      {
          return TRUE;
      } 
      __declspec(dllexport) void SANDBOX(int* arrayLength, int* intArray[])
      {
          if(*intArray == NULL)
          {
              *arrayLength = 5;
              return;
          }
          else
          {
              int i = 0;
              for(i = 0; i &lt; (*arrayLength); i++)
              {
                  (*intArray)[i] = 1 + i*i;
              }
          }
      }
  }
  </code></pre>
  
  <p>My C# application imports the method like so:</p>
  
  <pre><code>    const string dllFileLocation = "Wrapper.dll";
  
      [DllImport(dllFileLocation, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
      public extern static void SANDBOX(ref int arrayLength, ref int[] intArray);
  </code></pre>
  
  <p>And finally, my C# application calls the code in a form like this:</p>
  
  <pre><code>        //Initialize some things
          string outString;
          int numInArray = -1;
          int[] iArray = null;
          //Fill the numInArray integer
          Wrapper_Handle.SANDBOX(ref numInArray, ref iArray);
  
          //Lets initialize the array and print the values
          iArray = new int[numInArray];
          outString = "";
          foreach(int i in iArray)
          {
              outString += i + "\n";
          }
          MessageBox.Show(outString);
  
          //Now lets put values into the array and print the new ones out
          Wrapper_Handle.SANDBOX(ref numInArray, ref iArray);
          outString = "";
          foreach(int i in iArray)
          {
              outString += i + "\n";
          }
          MessageBox.Show(outString);
  </code></pre>
  
  <p>So, what I would expect to happen is I make a null array to get the number of values to initialize. So I get 5 out, make a new array, and print it. It get what I would expect: a message box with 0 five times. However, after the method is called again the second message box is simply the number 1, with no other values. It would appear that the other 4 values are "cut" off of the array, and the C# application cannot see them anymore.</p>
  
  <p>I have successfully imported many other functions from the C++ .DLL. Its this array notation which is causing issues. When debugging the .DLL, the values are properly passed to the C++ code, and they are assigned.</p>
  
  <p>Does anyone know why the C# application "loses" the other 4 values? It does not matter the length of the array, only the first value is ever kept after the call to the method.</p>
  
  <p>Thanks in advance. Any help is greatly appreciated.</p>
  
  <hr>
  
  <p>EDIT--
  The solution to my problem was provided in a comment to this question. I am posting my changes below:</p>
  
  <p>C++ .h file:</p>
  
  <pre><code>#pragma once
  namespace Wrapper {
  extern __declspec(dllexport)
      void SANDBOX(int arrayLength, int* intArray);
  }
  </code></pre>
  
  <p>C++ .cpp file:</p>
  
  <pre><code>#include "stdafx.h"
  #include "Wrapper.h"
  #include &lt;windows.h&gt;
  using namespace Wrapper;
  
  extern "C"{
  
      BOOL APIENTRY DllMain( 
                              HANDLE hModule,
                              DWORD  ul_reason_for_call,
                              LPVOID lpReserved )
      {
          return TRUE;
      } 
      __declspec(dllexport) void SANDBOX(int* arrayLength, int* intArray)
      {
          if(intArray == NULL)
          {
              *arrayLength = 5;
              return;
          }
          else
          {
              int i = 0;
              for(i = 0; i &lt; (*arrayLength); i++)
              {
                  (intArray)[i] = 1 + i*i;
              }
          }
      }
  }
  </code></pre>
  
  <p>C# import:</p>
  
  <pre><code>    const string dllFileLocation = "Wrapper.dll";
  
      [DllImport(dllFileLocation, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
      public extern static void SANDBOX(ref int arrayLength, int[] intArray);
  </code></pre>
  
  <p>C# calls:</p>
  
  <pre><code>        string outString;
          int numInArray = -1;
          int[] iArray = null;
  
          Wrapper_Handle.SANDBOX(ref numInArray, iArray);
          iArray = new int[numInArray];       
  
          outString = "";
          foreach(int i in iArray)
          {
              outString += i + "\n";
          }
  
  
          MessageBox.Show(outString);
          Wrapper_Handle.SANDBOX(ref numInArray, iArray);
          outString = "";
          foreach(int i in iArray)
          {
              outString += i + "\n";
          }
          MessageBox.Show(outString);
  </code></pre>