Why does C# exit when calling the Ada elaboration routine using debug?

Posted by erict on Stack Overflow See other posts from Stack Overflow or by erict
Published on 2014-05-27T23:26:21Z Indexed on 2014/05/29 15:28 UTC
Read the original article Hit count: 282

Filed under:
|
|

I have a DLL created in Ada using GPS. I am dynamically loading it and calling it successfully both from Ada and from C++.

But when I try to call it from C#, the program exits on the call to Elaboration init. What am I missing? The exact same DLL is perfectly happy getting called from C++ and Ada.

Edit: If I start the program without Debugging, it also works with C#. But if I run it with the Debugger, then it exits on the call to ElaborationInit. There are no indications in any of the Windows event logs.

If the Ada DLL is Pure, and I skip the elaboration init call, the actual function DLL is called correctly, so it has something to do with the elaboration.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace CallingDLLfromCS
{
   class Program
   {
      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern IntPtr LoadLibrary(string dllToLoad);

      [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
      public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

      [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
      public static extern bool FreeLibrary(IntPtr hModule);

      [UnmanagedFunctionPointer(CallingConvention.StdCall)]
      delegate int AdaCallable2_dlgt(int val);
      static AdaCallable2_dlgt fnAdaCallable2 = null;

      [UnmanagedFunctionPointer(CallingConvention.StdCall)]
      delegate void ElaborationInit_dlgt();
      static ElaborationInit_dlgt ElaborationInit = null;

      [UnmanagedFunctionPointer(CallingConvention.StdCall)]
      delegate void AdaFinal_dlgt();
      static AdaFinal_dlgt AdaFinal = null;

      static void Main(string[] args)
      {
         int result;
         bool fail = false;   // assume the best

         IntPtr pDll2 = LoadLibrary("libDllBuiltFromAda.dll");
         if (pDll2 != IntPtr.Zero)
         {
            // Note the @4 is because 4 bytes are passed.  This can be further reduced by the use of a DEF file in the DLL generation.
            IntPtr pAddressOfFunctionToCall = GetProcAddress(pDll2, "AdaCallable@4");
            if (pAddressOfFunctionToCall != IntPtr.Zero)
            {
               fnAdaCallable2 = (AdaCallable2_dlgt)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(AdaCallable2_dlgt));
            }
            else
               fail = true;

            pAddressOfFunctionToCall = GetProcAddress(pDll2, "DllBuiltFromAdainit");
            if (pAddressOfFunctionToCall != IntPtr.Zero)
            {
               ElaborationInit = (ElaborationInit_dlgt)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ElaborationInit_dlgt));
            }
            else
               fail = true;

            pAddressOfFunctionToCall = GetProcAddress(pDll2, "DllBuiltFromAdafinal");
            if (pAddressOfFunctionToCall != IntPtr.Zero)
               AdaFinal = (AdaFinal_dlgt)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(AdaFinal_dlgt));
            else
               fail = true;

            if (!fail)
            {
               ElaborationInit.Invoke();
//             ^^^^^^^^^^^^^^^^^^^^^^^^^    FAILS HERE
               result = fnAdaCallable2(50);
               Console.WriteLine("Return value is " + result.ToString());
               AdaFinal();
            }
            FreeLibrary(pDll2);
         }
      }
   }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about dll