title: C# using C library with pointer etc
body: <p>I have a .dll without source code.
  That library is wrote in C... I have only one .h
  An extract of the library is this:</p>
  
  <pre><code>typedef enum
  {
      SSHD_ERR_NONE = 0,
      SSHD_ERR_INVALID_HANDLE,
      SSHD_ERR_NULL_POINTER,
  }sshdErr_t;
  
  typedef struct
  {
      unsigned long  Year;            // 
      unsigned long  Month;       // 1...12
      unsigned long  Day;         // 1...31
  
      unsigned long  Hour;        // 0...23
      unsigned long  Min;         // 0...59
      unsigned long  Sec;         // 0...59
      unsigned long  MilliSec;    // 0...999
  } sshdDateTime_t;
  
  
      DllExport HANDLE sshdCreate(void);
      DllExport sshdErr_t sshdGetDllVersion(char *dllVersion, unsigned long dllVersionMaxLen);
  
      DllExport sshdErr_t sshdOpen(HANDLE rh);
  
  I have write this code:
  
  
  
        private const String dllPath = @"D:\work\SSHD.dll";
  
      [DllImport(dllPath,EntryPoint = "sshdOpen")]
          internal static extern eSSHD_Err Extern_sshdOpen();
  
  
          [DllImport(dllPath,EntryPoint = "sshdGetDllVersion")]
          //internal static extern string sshdGetDllVersion();
          internal static extern eSSHD_Err Extern_sshdGetDllVersion(string dllVer , Int32 maxLen );
  
          [DllImport(dllPath, EntryPoint = "sshdCreate")]
          internal static extern IntPtr Extern_sshdCreate();
  
      public enum eSSHD_Err {
          SSHD_ERR_NONE = 0,
          SSHD_ERR_INVALID_HANDLE,
          SSHD_ERR_NULL_POINTER,
      }
  
    public class SSHDDateTime {
      public ulong Year { get; set; }     // 
      public ulong Month { get; set; }    // 1...12
      public ulong Day { get; set; }      // 1...31
      public ulong Hour { get; set; }  // 0...23
      public ulong Min { get; set; }      // 0...59
      public ulong Sec { get; set; }    // 0...59
      public ulong MilliSec { get; set; } // 0...999
  
      public SSHDDateTime() {
        Year = 0;
        Month = 0;
        Day = 0;
        Hour = 0;
        Min = 0;
        Sec = 0;
        MilliSec = 0;
      }
    }
  </code></pre>
  
  <p>So I use Dll import, convert enum in enum (C#) and struct in class...</p>
  
  <p>When I try to use I have an error...</p>
  
  <p>Now the code for use the library:</p>
  
  <pre><code>  IntPtr handle;
    handle = Extern_sshdCreate();
  </code></pre>
  
  <p>this MAYBE work... It means that value of "handle" change.... but I really not know if it work!</p>
  
  <p>when I try to use the other function, in this way:</p>
  
  <pre><code>int retProva = (int) (Extern_sshdOpen(handle));
  </code></pre>
  
  <p>or</p>
  
  <pre><code>eSSHD_Err retProva = Extern_sshdOpen(handle);
  </code></pre>
  
  <p>I have an error of stack corrupted...</p>
  
  <p>Using the other function is the same results:</p>
  
  <pre><code>string dllVer="xxxxxxxxxxxxxxx";
  Int32 maxLen = 10;
  Extern_sshdGetDllVersion(dllVer,maxLen);
  </code></pre>
  
  <p>I try to use string or String for the dllVer or to use = "         " ...
  I try to store the retruned value and not
  I try to use Int32, string, ulong for maxLen 
  nut all try without result...</p>
  
  <p>the error returned, in Italian, is this:</p>
  
  <blockquote>
    <p>Managed Debugging Assistant 'PInvokeStackImbalance' : 'Una chiamata
    alla funzione PInvoke
    'TestSTSWavetronix!TestSTSWavetronix.FormTestWavetronix::Extern_sshdGetDllVersion'
    ha sbilanciato lo stack. Questo problema può verificarsi quando la
    firma PInvoke gestita non corrisponde alla firma di destinazione non
    gestita. Verificare che la convenzione di chiamata e i parametri della
    firma PInvoke corrispondano alla firma di destinazione non gestita.'</p>
  </blockquote>
  
  <p>So I ask:
  1. How to use correctly this call?
  2. I transform enum C in enum C#, but for return value, how to adapt?
  3. similar to previous, how to pass struct C to function, if in C# I have class instead?
  4. I have a pointer on C parameter function call... how to manage with him? I suppose that the C code try to modify the string that I pass....</p>
  
  <p>edit:
  other try:
  - use unsafe in compilation proprierties and before prototype 
  - use "enum : int"  on definition of enum</p>
  
  <p>edit 2:
  ********************** WORKING SOLUTION *************</p>
  
  <pre><code>  public enum eSSHD_Err {
      SSHD_ERR_NONE = 0,
      SSHD_ERR_INVALID_HANDLE,
      SSHD_ERR_NULL_POINTER,
  }
      [DllImport(dllPath,EntryPoint = "sshdGetDllVersion",CallingConvention = CallingConvention.Cdecl)]
      unsafe internal static extern eSSHD_Err Extern_sshdGetDllVersion(ref char dllVer,Int32 maxLen);
  char[] dllVer = new char[250];
  Int32 maxLen = 250;
  retErrGetDllVer = Extern_sshdGetDllVersion(ref dllVer[0],maxLen);
  </code></pre>
  
  <p>Thanks to all</p>
  
  <p>Massimiliano</p>