title: my c++ and c# interop crashes in 64 bit, why? pointer size?
body: <p>i got a native 32 bit dll (no source) which runs as a plugin in an application i use. I've done another native dll myself which will communicate with that plugin in order to create and update the plugin's controls. 
  From that dll i've exported the functions I need in order to control the plugin from my c# application (with p/invoke).</p>
  
  <p>here's the code:</p>
  
  <p>h file:</p>
  
  <pre><code>#pragma once
  
  #include "include\SpoutControls.h"
  
  extern "C" { __declspec(dllexport) void InitializeControls(char *sendername, int *numControls, char** names, int *types, float* floats, float* toggles, float* press, char** text); }
  extern "C" { __declspec(dllexport) bool UpdateControls(const char** text, float *floats, float *toggles, float *press, int *numControls); }
  extern "C" { __declspec(dllexport) void CloseControls(); }
  //
  extern "C" __declspec(dllexport) int ReleaseMemory(float *pArray)
  {
      delete[] pArray;
      //delete[] Usize;
      return 0;
  };
  </code></pre>
  
  <p>the cpp:</p>
  
  <pre><code>#include "SpoutControls4vvvv.h"
  
  //SpoutControls and the functions
  //CreateControl, OpenControls, CheckControls, CloseControls
  //are declared in SpoutControls.h, which comes with the 32 bit plugin dll
  SpoutControls spoutcontrols;
  
  void InitializeControls(char *sendername, int *numControls, char** names, int *types, float* floats, float* toggles, float* press, char** text) {
  
      int Vcontrols = numControls[0];
      int Tcontrols = numControls[1];
      int Pcontrols = numControls[2];
      int Scontrols = numControls[3];
  
      int all = Vcontrols + Tcontrols + Pcontrols + Scontrols;
      int v=0, t=0, p=0, s = 0;
  
      for (int controlID = 0; controlID &lt; all; controlID++) {
  
          if (types[controlID] == 0) {
              spoutcontrols.CreateControl(names[controlID], "float",0.0,1.0, floats[v]);
              v++;
          }
          if (types[controlID] == 1) {
              spoutcontrols.CreateControl(names[controlID], "bool", toggles[t]);
              t++;
          }
          if (types[controlID] == 2) {
              spoutcontrols.CreateControl(names[controlID], "event", press[p]);
              p++;
          }
          if (types[controlID] == 3) {
              spoutcontrols.CreateControl(names[controlID], "text", text[s]);
              s++;
          }
  
      }
  
      spoutcontrols.OpenControls(sendername);
  }
  
  
  bool UpdateControls(const char** text, float *floats, float *toggles, float *press, int *numControls) {
      int Vcontrols = numControls[0];
      int Tcontrols = numControls[1];
      int Pcontrols = numControls[2];
      int Scontrols = numControls[3];
  
      int all = Vcontrols + Tcontrols + Pcontrols + Scontrols;
      int v = 0, t = 0, p = 0, s = 0;
  
  
  
      if (spoutcontrols.CheckControls(myControls)) {
  
          for (int controlID = 0; controlID &lt; all; controlID++) {
  
              if (myControls[controlID].type == 10) {
                  floats[v] = myControls[controlID].value;
                  v++;
              }
              if (myControls[controlID].type == 0) {
                  toggles[t] = myControls[controlID].value;
                  t++;
              }
              if (myControls[controlID].type == 1) {
                  press[p] = myControls[controlID].value;
                  p++;
              }
              if (myControls[controlID].type == 100) {
                  text[s] = myControls[controlID].text.data();
                  s++;
              }
  
          }
          return true;
      }
      return false;
  }
  
  void CloseControls() {
      spoutcontrols.CloseControls();
  }
  </code></pre>
  
  <p>and here's the c# code:</p>
  
  <pre><code>public unsafe class SystemSpoutSenderNode: IDisposable
      {
  
          [System.Runtime.InteropServices.DllImport("SpoutControls4vvvv.dll")]
          private static extern void InitializeControls(IntPtr sendername, IntPtr numControls,String[] names, IntPtr types, IntPtr floats, IntPtr toggles, IntPtr press, String[] text);
          [System.Runtime.InteropServices.DllImport("SpoutControls4vvvv.dll")]
          private static extern int CloseControls();
          [System.Runtime.InteropServices.DllImport("SpoutControls4vvvv.dll", CallingConvention = CallingConvention.Cdecl)]
          private static extern bool UpdateControls([In, Out] String[] text, [In, Out] float[] floats,  [In, Out] float[] toggles, [In, Out] float[] press, IntPtr numControls);
          [System.Runtime.InteropServices.DllImport("SpoutControls4vvvv.dll")]
          private static extern int ReleaseMemory(IntPtr ptr);
  
  
      public void Evaluate(int SpreadMax)
              {           
                          //countControls determines number of controls per type (string,float,toggle,click)                                  
                          int[] controls = countControls(FType);
                          //sumControls will just add up all elements in controls
                          int all = sumControls(controls);
  
                          //in my code these arrays will get filled with values, deleted here for readability         
                          String[] names = new String[all];   
                          int[] types = new int[all]; 
                          float[] floats = new float[controls[0]];
                          float[] toggles = new float[controls[1]];
                          float[] press = new float[controls[2]];
  
                          String[] text = new String[controls[3]];
  
                          //initialze return arrays
                          String[] Rtext = new String[controls[3]];
                          float[] Rfloats = new float[controls[0]];
                          float[] Rtoggles = new float[controls[1]];
                          float[] Rpress = new float[controls[2]];
  
                          //allocate pointers
                          IntPtr SndrNamePtr = NativeUtf8FromString(FSenderName);
                          IntPtr BinPtr = Marshal.AllocHGlobal(4*sizeof(int));                
                          IntPtr TypePtr = Marshal.AllocHGlobal(all*sizeof(int));
                          IntPtr FloatPtr = Marshal.AllocHGlobal(controls[0]*sizeof(float));
                          IntPtr TogglePtr = Marshal.AllocHGlobal(controls[1]*sizeof(float));
                          IntPtr PressPtr = Marshal.AllocHGlobal(controls[2]*sizeof(float));
  
                          try
                              {           
                              //copy control info + defaults to pointer   
                              Marshal.Copy(controls, 0, BinPtr, 4);
                              Marshal.Copy(types, 0, TypePtr, all);
                              Marshal.Copy(floats, 0, FloatPtr, controls[0]);
                              Marshal.Copy(toggles, 0, TogglePtr, controls[1]);
                              Marshal.Copy(press, 0, PressPtr, controls[2]);
  
                              //initialize controls   
                              if (FWrite) InitializeControls(SndrNamePtr,BinPtr,names,TypePtr,FloatPtr,TogglePtr,PressPtr,text);
  
                              //update controls
                              bool changed = UpdateControls(Rtext,Rfloats,Rtoggles,Rpress,BinPtr);
  
  
                              //FF, FT, FS and FP are the outputs in my c# host
                              if (changed){
  
                                  for(int j=0; j&lt;controls[0];j++){
                                  FF[j]=Rfloats[j];
                                  }           
                                  for(int j=0; j&lt;controls[1];j++){
                                  FT[j]=FloatToBool(Rtoggles[j]);
                                  }
                                  for(int j=0; j&lt;controls[3];j++){
                                  FS[j]=Rtext[j];
                                  }
                              }
  
                              for(int j=0; j&lt;controls[2];j++){
                                  FP[j]=FloatToBool(Rpress[j]);
                                  }
  
                              }
  
                          finally
                          {
                              Marshal.FreeHGlobal(SndrNamePtr);
                              Marshal.FreeHGlobal(BinPtr);
                              Marshal.FreeHGlobal(FloatPtr);
                              Marshal.FreeHGlobal(TogglePtr);
                              Marshal.FreeHGlobal(PressPtr);  
                          }
                      }
                  }   
              }
  
              public void Dispose()
              {
                  CleanUp();
                  CloseControls();
              }
  }
  </code></pre>
  
  <p>NOTE: the c# code runs without precompiling in a frame-based, c# host environment for graphical programming (<a href="http://vvvv.org" rel="nofollow">vvvv</a>), therefore i've deleted host specific decalarations of inputs (FType,FSenderName) and outputs (FF,FS,FP,FT) to avoid confusion. These will be used to "connect" this code with other functionality. Evaluate will be called every frame by the host.</p>
  
  <p>Now to the actual question(s):</p>
  
  <p>it's working fine so far in 32 bit, but in 64 bit my c# host crashes without any message. after some reading i believe this is due to pointer sizes being different in 32/64bit systems, but i'm not exactly sure what to do/if this actually applies here. I would be very thankful if you could </p>
  
  <ul>
  <li>explain me how (and why) to get this code to run in 64 bit</li>
  <li>point out any other mistakes you might spot along the way- i'm completely new to c++ and still a beginner in c#, so i'm pretty confident there's a lot to improve here; especially: memory leaks and passing the values from c++ to c# and vice versa...uiuiui.</li>
  </ul>
  
  <p>I've understood that I shouldn't cast a pointer to an int in 64 bit, so the last thing I've tried is to change from</p>
  
  <pre><code>int Vcontrols = numControls[0];
  int Tcontrols = numControls[1];
  int Pcontrols = numControls[2];
  int Scontrols = numControls[3];
  </code></pre>
  
  <p>to </p>
  
  <pre><code>int Vcontrols = (INT_PTR)numControls[0];
  int Tcontrols = (INT_PTR)numControls[1];
  int Pcontrols = (INT_PTR)numControls[2];
  int Scontrols = (INT_PTR)numControls[3];
  </code></pre>
  
  <p>but with no luck, therefore I'm posting my original problem, even if this is a correct improvement(?).</p>
  
  <p>EDIT: thanks to @dkackman for pointing out one unclear point: my cpp code calls functions which come as source code (SpoutControls.h) with the native 32 bit dll. It's not the source for the 32 bit dll itself but declares the functions used to (as far as i can tell) access the same shared memory as the 32 bit dll.
  I can also copy paste the code here if this might be the problem?
  Also can be found <a href="https://github.com/leadedge/SpoutControls/tree/master/SOURCE" rel="nofollow">here</a></p>
  
  <p>thank you.</p>