title: C++/CLI noob: System.AccessViolationException
body: <p>I'm trying to put together a "cool demo" for a career day at my daughter's jr. high in 5 days and so I'm trying to use <a href="https://github.com/echonest/echoprint-codegen" rel="nofollow noreferrer">the echoprint library</a> to perform over the air (OTA) audio recognition. I've never really gone much farther than "hello world" in C++ and I am trying to use C++/CLI to wrap the echoprint codegen library so I can call it from C#. Here's my header file:</p>
  
  <pre><code>// echoprint-cli.h
  
  #pragma once
  
  #include "Codegen.h";
  
  using namespace System;
  
  namespace echoprintcli {
  
      public ref class CodegenCLI
      {
      public:
          String^ getCodeString(array&lt;float&gt;^ buffer, unsigned int samples, int start_offset);
      };
  }
  </code></pre>
  
  <p>Here's my implementation:</p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;msclr\marshal_cppstd.h&gt;
  #include "echoprint-cli.h"
  
  using namespace System;
  using namespace System::Runtime::InteropServices;
  using namespace msclr::interop;
  
  namespace echoprintcli {
      String^ CodegenCLI::getCodeString(array&lt;float&gt;^ buffer, unsigned int samples, int start_offset){
          String^ result = String::Empty;
  
          if(buffer-&gt;Length &gt; 0){
              GCHandle h = GCHandle::Alloc(buffer, System::Runtime::InteropServices::GCHandleType::Pinned);
  
              try{
                  float* pcm = (float*)(void*)h.AddrOfPinnedObject();
                  Codegen* codegen = new Codegen(pcm, samples, start_offset); //System.AccessViolationException here
                  std::string code;
                  try{
                      code = codegen-&gt;getCodeString();
                  }finally{
                      delete codegen;
                  }
                  result = marshal_as&lt;String^&gt;(code);
              }
              finally{
                  h.Free();
              }
          }
          return result;
      }
  }
  </code></pre>
  
  <p>I'm using the XNA Microphone class to record the audio. It returns an array of byte[], so I'm converting the bytes to float and then passing it thru my wrapper to the Codegen class like this (C#):</p>
  
  <pre><code>        var mic = Microphone.Default;
          Log(String.Format("Using '{0}' as audio input...", mic.Name));
          var buffer = new byte[mic.GetSampleSizeInBytes(TimeSpan.FromSeconds(22))];
  
          int bytesRead = 0;
          string fileName = String.Empty;
  
          try
          {
              mic.Start();
              try
              {
                  Log(String.Format("{0:HH:mm:ss} Start recording audio stream...", DateTime.Now));
                  while (bytesRead &lt; buffer.Length)
                  {
                      Thread.Sleep(1000);
                      var bytes = mic.GetData(buffer, bytesRead, (buffer.Length - bytesRead));
                      Log(String.Format("{0:HH:mm:ss} Saving {1} bytes to stream...", DateTime.Now, bytes));
                      bytesRead += bytes;
                  }
                  Log(String.Format("{0:HH:mm:ss} Finished recording audio stream...", DateTime.Now));
              }
              finally
              {
                  mic.Stop();
              }
  
              Func&lt;byte, float&gt; convert = (b) =&gt; System.Convert.ToSingle(b);
              var converter = new Converter&lt;byte, float&gt;(convert);
              float[] pcm = Array.ConvertAll&lt;byte, float&gt;(buffer, converter);
  
              Log(String.Format("{0:HH:mm:ss} Generating audio fingerprint...", DateTime.Now));
              var codeg = new CodegenCLI();
              String code = codeg.getCodeString(pcm, (uint)pcm.Length, 0);
  </code></pre>
  
  <p>But when my C++/CLI method (getCodeString) calls into the native method I get Sysetem.AccessViolationException. </p>
  
  <p>The entire source code is available as a VS 2010 SP1 or VS 11 solution on github: <a href="https://github.com/developmentalmadness/echoprint-net/tree/3c48d3783136188bfa213d3e9fd1ebea0f151bed" rel="nofollow noreferrer">https://github.com/developmentalmadness/echoprint-net/tree/3c48d3783136188bfa213d3e9fd1ebea0f151bed</a></p>
  
  <p>That URL should point to the revision that's currently experiencing the problem. </p>
  
  <p><strong>EDIT</strong>
  I tried the suggestion here: <a href="https://stackoverflow.com/questions/4396589/accessviolation-when-calling-c-dll-from-c-cli">AccessViolation, when calling C++-DLL from C++/CLI</a></p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;msclr\marshal_cppstd.h&gt;
  #include "echoprint-cli.h"
  
  using namespace System;
  using namespace System::Runtime::InteropServices;
  using namespace msclr::interop;
  
  namespace echoprintcli {
      String^ CodegenCLI::getCodeString(array&lt;float&gt;^ buffer, unsigned int samples, int start_offset){
          String^ result = String::Empty;
  
          IntPtr p = Marshal::AllocHGlobal(buffer-&gt;Length * sizeof(float));
          try{
              pin_ptr&lt;float&gt; pcm = static_cast&lt;float*&gt;(p.ToPointer());
              Codegen* codegen = new Codegen(pcm, samples, start_offset); // System.AccessViolationException here
              std::string code;
              try{
                  code = codegen-&gt;getCodeString();
              }finally{
                  delete codegen;
              }
              result = marshal_as&lt;String^&gt;(code);
          }
          finally{
              Marshal::FreeHGlobal(p);
          }
          return result;
      }
  }
  </code></pre>
  
  <p>And I still get the access violation, but after crashing the debugger dropped me into the native code (I have no idea how to get there myself). And it bombs inside the ctor. The pointer (pcm) has an address an a value of 0.0000000 but I can't figure out how to debug into the code myself other than to show the source here:</p>
  
  <pre><code>    Codegen::Codegen(const float* pcm, unsigned int numSamples, int start_offset) {
      if (Params::AudioStreamInput::MaxSamples &lt; (uint)numSamples)
          throw std::runtime_error("File was too big\n");
  
      Whitening *pWhitening = new Whitening(pcm, numSamples); //System.AccessViolationException
  </code></pre>
  
  <p>Without being able to debug, I can only assume to follow down the stack two steps:</p>
  
  <pre><code>    Whitening::Whitening(const float* pSamples, uint numSamples) :
      _pSamples(pSamples), _NumSamples(numSamples) {
      Init();
  }
  </code></pre>
  
  <p>And I imagine it bombs in the Init() method somewhere:</p>
  
  <pre><code>    void Whitening::Init() {
      int i;
      _p = 40;
  
      _R = (float *)malloc((_p+1)*sizeof(float));
      for (i = 0; i &lt;= _p; ++i)  { _R[i] = 0.0; }
      _R[0] = 0.001;
  
      _Xo = (float *)malloc((_p+1)*sizeof(float));
      for (i = 0; i &lt; _p; ++i)  { _Xo[i] = 0.0; }
  
      _ai = (float *)malloc((_p+1)*sizeof(float));
      _whitened = (float*) malloc(sizeof(float)*_NumSamples);
  }
  </code></pre>