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);
}
}
}
}