title: C# Marshalling for C Struct and Function
body: <p>I have the following C Header/Code Example:</p>
  
  <hr>
  
  <p>Header file</p>
  
  <hr>
  
  <pre><code>struct category_info {
   int id;
   const char *name;
   const char *description;
  };
  
  
  DLLEXPORT
  void* xyz_categories_info(struct category_info **info, size_t *info_count);
  </code></pre>
  
  <hr>
  
  <p>Example C Snippet</p>
  
  <hr>
  
  <pre><code>struct category_info *catinfo;
  
  size_t catcount;
  size_t i;
  int max_name_len = 0;
  void *catmem = xyz_categories_info(&amp;catinfo, &amp;catcount)
  </code></pre>
  
  <hr>
  
  <hr>
  
  <p>Which I would like to convert to c#...</p>
  
  <p>My First GUESS (and its a guess) is:</p>
  
  <pre><code>[StructLayout(LayoutKind.Sequential)]
      public struct category_info
      {
          int id;
          [MarshalAs(UnmanagedType.LPStr)]
          StringBuilder name;
          [MarshalAs(UnmanagedType.LPStr)]
          StringBuilder description;
      };
  </code></pre>
  
  <p>[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]<br>
          public static extern IntPtr xyz_categories_info([Out]category_info cat, [Out]int catSize);</p>
  
  <p>But it just doesn't look right..</p>
  
  <p>Any suggestions.. Once the above is declared correctly in C#.. How should it be accessed in C# </p>
  
  <pre><code>category_info catinfo;
  </code></pre>
  
  <p>catmem = xyz_categories_info(out catinfo, out catcount);</p>
  
  <p>??????</p>
  
  <p>Any help greatly appreciated.</p>
  
  <p>Thanks</p>
  
  <p>================================================================================</p>
  
  <h1>Update 2</h1>
  
  <p>The memory allocated in xyz_categories_info is freed using this C call:</p>
  
  <pre><code>void xyz_categories_info_free(void *p);
  </code></pre>
  
  <p>Below is an example of it being used in C.... Hope this explains it a bit more..</p>
  
  <pre><code>    category_buffer = xyz_categories_info(&amp;category_info, &amp;category_count);
  
  if( !category_buffer ) 
      {
      // Failed Log a message and exit.
      exit(1);
  }
  
  for(j=0; j&lt;category_count; j++) 
      {
      if( category_info[j].id == 0 )
          continue;
  
      printf("id: %d name: '%s' description: '%s'\n",
          category_info[j].id,
          category_info[j].name,
          category_info[j].description
      );
  }
  
  xyz_categories_info_free(category_buffer);
  </code></pre>