title: Pinvoke - callback from C++, arrays passed between functions have unexpected size
body: <p>EDIT: I've updated the code given the suggestions in @Hans Passant's comment and @David Heffernan's answer.</p>
  
  <p>The argument <code>c</code> is no longer null, but both <code>x</code> and <code>c</code> still have length one when they are passed back to <code>CallbackFunction</code>.</p>
  
  <p>I am trying to write C# code that passes a function pointer (using a delegate) to a C++ function, which calls the function pointer.</p>
  
  <p>Code is below.</p>
  
  <p>The problem I'm having is that when the C++ function <code>f</code> calls <code>fnPtr(x,c)</code>, in the C# function <code>CallbackFunction</code>, <code>x</code> has one element (with the correct value of 1.0), and <code>c</code> is null. I have no idea what the problem is.</p>
  
  <p>I can't change the signature of MyCallback.</p>
  
  <p>C# code:</p>
  
  <pre><code>using System.Runtime.InteropServices;
  
  namespace PInvokeTest
  {
      class Program
      {
          [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
          private delegate double MyCallback(
              [In] double[] x,
              [Out] double[] c);
  
          private static double CallbackFunction(
              [In] double[] x,
              [Out] double[] c)
          {
              c[0] = x[0] + x[1] + x[2];
              c[1] = x[0] * x[1] * x[2];
              return c[0] + c[1];
          }
  
          private static MyCallback _myCallback;
  
          [DllImport("NativeLib", CallingConvention = CallingConvention.StdCall)]
          private static extern int f(MyCallback cf);
  
          private static void Main()
          {
              _myCallback = new MyCallback(CallbackFunction);
              f(_myCallback);
          }
      }
  }
  </code></pre>
  
  <p>NativeLib.h:</p>
  
  <pre><code>#ifndef _NATIVELIB_H_
  #define _NATIVELIB_H_
  
  #ifndef MYAPI
    #define MYAPI 
  #endif
  
  #ifdef __cplusplus
  extern "C"
  {
  #endif
  
  #ifdef _WIN32
    #ifdef MAKE_MY_DLL
      #define MYAPI __declspec(dllexport) __stdcall
    #else
      #define MYAPI __stdcall
    #endif
  #else
    #if __GNUC__ &gt;= 4
      #define MYAPI __attribute__ ((visibility ("default")))
    #else
      #define MYAPI
    #endif
  #endif
  
    typedef int MyCallback(const double * x,
      double * c);
  
    MYAPI int f(MyCallback * fnPtr);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif // _NATIVELIB_H_
  </code></pre>
  
  <p>NativeLib.cpp:</p>
  
  <pre><code>#include "NativeLib.h"
  #include &lt;stdio.h&gt;
  #include &lt;malloc.h&gt;
  
  MYAPI int f(MyCallback * fnPtr)
  {
    double x[] = { 1.0, 2.0, 3.0 };
    double c[] = { 0.0, 0.0, 0.0 };
  
    printf("%e\n", fnPtr(x, c));
  
  
    return 0;
  }
  </code></pre>