title: Is it legal to have private data in PInvoke friendly structs/classes?
body: <p>I was wondering whether it was in any sense illegal to make data members <code>private</code> for the structs/classes which will be used with PInvoke. The motivation is that there are some pretty big C structs in the API I need to use and I would rather avoid making wrappers for every single one of my PInvoke friendly structs to hide the data. At the same time, I do not want to leave all the data members public.</p>
  
  <p>Trying out an example: <br/>
  C/C++ Code:</p>
  
  <pre><code>//PInvokeProvider.h
  #include "stdafx.h" 
  typedef struct Animal_s
  {
      char Name[10000];
  } Animal;
  
  extern "C" void __declspec(dllexport) ChangeName(Animal* pAnimal);
  
  
  //PInvokeProvider.cpp    
  #include "stdafx.h"
  #include &lt;stdio.h&gt;
  #include "PInvokeProvider.h"
  
  extern "C" {
      void ChangeName(Animal* pAnimal)
      {
          printf("Entered C++\n");
          printf("Recieved animal : %s\n", pAnimal-&gt;Name);
          printf("This function will change the first letter of animal to 'A'\n");
          pAnimal-&gt;Name[0] = 'A';
          printf("Animal changed to : %s\n", pAnimal-&gt;Name);
          printf("Leaving C++\n");
      }
  }
  </code></pre>
  
  <p>C#:</p>
  
  <pre><code>namespace PInvokeConsumer
  {
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
      public struct Animal
      {
          /// char[10000]
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10000)]
          private string _name;
  
          public Animal(string name)
          {
              _name = name;
          }
  
          public string Name
          {
              get { return _name; }
          }
      }
  
      public partial class NativeMethods
      {
          [DllImportAttribute("PInvokeProvider.dll", EntryPoint = "ChangeName", CallingConvention = CallingConvention.Cdecl)]
          public static extern void ChangeName(ref Animal pAnimal);
      }
  
      internal class Program
      {
          public static void Main(string[] args)
          {
              Animal animal = new Animal("Gorilla");
              NativeMethods.ChangeName(ref animal);
              Console.WriteLine(animal.Name);
              Console.Read();
          }
      }
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>Entered C++
  Recieved animal : Gorilla
  This function will change the first letter of animal to 'A'
  Animal changed to : Aorilla
  Leaving C++
  Aorilla
  </code></pre>
  
  <p>So in this example there weren't any problems using the struct with private data in C# (as long as private data matched the public data of C struct).</p>
  
  <p>Also when I check <code>Marshal.SizeOf()</code> on animal struct the size returned is <code>10,000</code> equal to the only data member that exists in the animal class, which makes me think that there is simply no space for any meta data passed to PInvoke calls and only the data location is passed, which would allow C/C++ code to completely disregard whatever our protection level in C# is. The question still stands whether there is something else I am overlooking by making data members private in C# for PInvoke friendly structs/classes.</p>