title: Trouble with passing handle to managed object using PInvoke
body: <p>I'm quite confused about how to pass handle to my managed object from .Net to unmanaged code. Now I'm developing kind of "driver" for Oracle Siebel CRM using C#. And how i faced with problem about how to pass handle to 
  Driver API have such method: </p>
  
  <pre><code>ISCAPI ISC_RESULT CreateISCDriverInstance
  /* in */(const ISC_STRING mediaTypeStr,
  /* in */ const ISC_STRING languageCode,
  /* in */ const ISC_STRING connectString,
  /* in */ const struct ISC_KVParamList* datasetParams,
  /* out */ ISC_DRIVER_HANDLE* handle);
  </code></pre>
  
  <p>And i have the problem with last parameter ISC_DRIVER_HANDLE* handle. I want to say that it may looks quite weird, but i don't have a definition of ISC_DRIVER_HANDLE type. </p>
  
  <p>As far as I know it's possible to use GCHandle to work with this... And here is my vision about how it should be implemented:</p>
  
  <pre><code>    [STAThread]
  [DllExport("CreateISCDriverInstance", CallingConvention = CallingConvention.StdCall)]
  public static int CreateIscDriverInstance([MarshalAs(UnmanagedType.LPWStr)] string mediaTypeStr,
      [MarshalAs(UnmanagedType.LPWStr)] string languageCode,
      [MarshalAs(UnmanagedType.LPWStr)] string connectString,
      [In] ref IscKvParamList datasetParams,
      out IntPtr handle)
  {
  ... // Here I'm doing something with incoming data
  var drvEntryPointHandle = GCHandle.Alloc(EntryPoints, GCHandleType.Pinned);
  handle = GCHandle.ToIntPtr(drvEntryPointHandle);
  return (int) ScErrorCode.ScEcOk; 
  }
  </code></pre>
  
  <p>But, after call of this method i'll get the CLR crash: (i'm terrible sorry about amount of traces)</p>
  
  <pre><code>ModLoad: C:\Debug\DriverLibrary.dll
  ModLoad: C:\Windows\SysWOW64\MSCOREE.DLL
  ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscoreei.dll
  ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
  ModLoad: C:\Windows\SysWOW64\MSVCR120_CLR0400.dll
  (730.4a4): Unknown exception - code 04242420 (first chance)
  ModLoad: C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\d1265d6159ea876f9d63ea4c1361b587\mscorlib.ni.dll
  ModLoad: \DriverLibrary.dll
  ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
  ModLoad: C:\Windows\Microsoft.NET\Framework\v4.0.30319\diasymreader.dll
  ModLoad: NLog.dll
   .......................................
  ModLoad: C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Runteb92aa12#\ad1a5e8488b493088c4317191604dc81\System.Runtime.Serialization.ni.dll
  (730.4a4): Access violation - code c0000005 (first chance)
  First chance exceptions are reported before any exception handling.
  This exception may be expected and handled.
  </code></pre>
  
  <p>Question is: <strong>How to pass handle to managed object from .Net in to unmanaged application?</strong>
  p.s. Additional info. 
  Lack of information is main problem here. Documentation provided by Oracle are very confusing and incomplete.
  If anyone have some doubts about efforts that have been applied to information retrieval... Here is a link to original documentation <a href="https://docs.oracle.com/cd/E14004_01/books/PDF/SiebCTIAdm.pdf" rel="nofollow">https://docs.oracle.com/cd/E14004_01/books/PDF/SiebCTIAdm.pdf</a> (starts from 260p.). </p>
  
  <p>But I have some example which were written in Delphi about 10 years ago.
  I'll provide some code from there which I think may be useful. 
  1) Function CreateISCDriverInstance(in TicISCCommunicationDriver class)</p>
  
  <pre><code>function CreateISCDriverInstance(const AMediaTypeStr, ALanguageCode,
    AConnectString: PWideChar; const AParams: TISCNamedParamList;
    out ADriverHandle: THandle): HRESULT;
  begin
    try
      ADriverHandle := TicISCCommunicationDriver.CreateInstance(AParams).Handle;
      Result := SC_EC_OK;
    except
      Result := SC_EC_DRIVER_CREATION_ERR;
    end;
  end;
  </code></pre>
  
  <p>2) Part or TicISCCommunicationDriver defenition:</p>
  
  <pre><code>TicISCCommunicationDriver = class(TObject)
    strict private
      class var
        FInstance: TicISCCommunicationDriver;
        ...
      var
        FHandle: THandle;
        ...
  </code></pre>
  
  <p>3) Constructor:
      class function TicISCCommunicationDriver.CreateInstance(const AParams: TISCNamedParamList): TicISCCommunicationDriver;
      begin
        if not Assigned(FInstance) then
          FInstance := TicISCCommunicationDriver.Create(AParams);
        Result := FInstance;
      end;</p>
  
  <pre><code>constructor TicISCCommunicationDriver.Create(const AParams: TISCNamedParamList);
  var
    IsDebug: boolean;
  begin
    inherited Create;
    FHandle := THandle(@Self);
      ...
     end;
  </code></pre>
  
  <p>I've never developed anything in Delphi, but, as far as i can get - it's singleton pattern implemented on Delphi. And <code>FHandle:THandle</code> it's just a handle to instance of TicISCCommunicationDriver. 
  After search in Google i found that THandle it's a handle identifying a globally allocated dynamic memory object. 
  p.p.s. 
  Also i tried to find the solution using HandleRef, but it doesn't helped too. </p>