title: Marshalling simple and complex datatypes to/from Object^% / void*
body: <p>I guess this will be simple for C++/CLI gurus.</p>
  
  <p>I am creating a wrapper which will expose high-performance C++ native classes to C# WinForms application.
  Everything went fine with simple known objects and I could wrap also a callback function to delegate. But now I am a bit confused.</p>
  
  <p>The native C++ class has a following method:</p>
  
  <pre><code>int GetProperty(int propId, void* propInOut)
  </code></pre>
  
  <p>At first I thought I could use void* as IntPtr, but then I found out that I need to access it from C#.  So I thought about a wrapper method:</p>
  
  <pre><code>int GetProperty(int propId, Object^ propInOut)
  </code></pre>
  
  <p>but as I looked through the C++ source, I found out that the method needs to modify the objects. So obviously I need:</p>
  
  <pre><code>int GetProperty(int propId, Object^% propInOut)
  </code></pre>
  
  <p>Now I cannot pass Objects to native methods so I need to know how to treat them in the wrapper. As the caller should always know what kind of data he/she is passing/receiving, I declared a wrapper:</p>
  
  <pre><code>int GetProperty(int propId, int dataType, Object^% propInOut)
  </code></pre>
  
  <p>I guess, I can use it to pass reference and value types, for example, an int like this:</p>
  
  <pre><code>Object count = 100; // yeah, I know boxing is bad but this will not be real-time call anyway
  myWrapper.GetProperty(Registry.PROP_SMTH, DATA_TYPE_INT, ref count);
  </code></pre>
  
  <p>I just added a bunch of dataType constants for all the data types I need:</p>
  
  <pre><code>DATA_TYPE_INT, DATA_TYPE_FLOAT, DATA_TYPE_STRING, DATA_TYPE_DESCRIPTOR, DATA_TYPE_BYTE_ARRAY
  </code></pre>
  
  <p>(DATA_TYPE_DESCRIPTOR is a simple struct with two fields: int Id and wstring Description - this type will be wrapped too, so I guess marshaling will be simple copying data back and forth; all the native strings are Unicode).</p>
  
  <p>Now, the question is - how to implement the wrapper method for all these 5 types?
  When I can just cast Object^% to something (is int, float safe to do that?) and pass to native method, when do I need to use pin_ptr and when I need some more complex marshaling to native and back?</p>
  
  <pre><code>int GetProperty(int propId, int dataType, Object^% propInOut)
  {
      if(dataType == DATA_TYPE_INT)
      {
          int* marshaledPropInOut = ???
          int result = nativeObject-&gt;GetProperty(propId, (void*)marshaledPropInOut);
          // need to do anything more?
          return result;
      }
  else
      if(dataType == DATA_TYPE_FLOAT)
      {
          float* marshaledPropInOut = ???
          int result = nativeObject-&gt;GetProperty(propId, (void*)marshaledPropInOut);
          // need to do anything more ?
          return result;
      }
  else
      if(dataType == DATA_TYPE_STRING)
      {
          // will pin_ptr be needed or it is enough with the tracking reference in the declaration?
          // the pointers won't get stored anywhere in C++ later so I don't need AllocHGlobal
          int result = nativeObject-&gt;GetProperty(propId, (void*)marshaledPropInOut);
          // need to do anything more?
          return result;
      }
  else
      if(dataType == DATA_TYPE_BYTE_ARRAY)
      {
           // need to convert form managed byte[] to native char[] and back; 
           // user has already allocated byte[] so I can get the size of array somehow
  
           return result;
      }
  else
      if(dataType == DATA_TYPE_DESCRIPTOR)
      {
           // I guess I'll have to do a dumb copying between native and managed struct, 
           // the only problem is pinning of the string again before passing to the native
  
           return result;
      }
  
      return -1;
  }
  </code></pre>
  
  <p>P.S. Maybe there is a more elegant solution for wrapping this void* method with many possible datatypes?</p>