I'm trying to dynamically call unmanaged C++ Dll from within my Web API. For this reason, I created 2 Controller Action:
(1) One is starting the dll: It uses the LoadLibrary to load the dll, and call an init-method in the dll, initializing some parameters for calculation.
(2) Here's is were I need the calculation result from my Dll (using the handle from LoadLibrary in Action 1, I use GetProcAdress to locate the function and create the delegate).
It seems to work fine, but when calling it multiple times, it hangs up - and this very sporadically and unpredictable. When I pause the debugging with Visual Studio, it is paused at my delegate-call for the function...
Can someone please help me?
Here's my code:
Expand|Select|Wrap|Line Numbers
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr LoadLibrary(string dllToLoad);
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate bool DllTransfer(ref WebCalcInfo Info);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private delegate bool InitDll([MarshalAs(UnmanagedType.LPStr)]string pExternPath);
- //This method is called in 1. Action
- public static bool LoadInitLibrary(string path)
- {
- if (!IsLoaded)
- {
- PATH = path;
- if (!Directory.Exists(PATH) && !File.Exists(PATH_DLL))
- throw new Exception(string.Format("Dll not found: {0}.", PATH_DLL));
- //LoadLibrary
- hModule = DllInterop.LoadLibrary(PATH_DLL);
- IsLoaded = (hModule != IntPtr.Zero);
- if (!IsLoaded)
- {
- int errno = Marshal.GetLastWin32Error();
- throw new Exception(string.Format("Failed to load library. Error:{0}.", errno));
- }
- //GetPointer: PROC_InitDll
- IntPtr intPtrInitDll = DllInterop.GetProcAddress(hModule, PROC_InitDll);
- if (intPtrInitDll == IntPtr.Zero)
- {
- int errno = Marshal.GetLastWin32Error();
- FreeLibrary();
- throw new Exception(string.Format("Process Address not found: PROC_InitDll is IntPtr.Zero. Error:{0}.", errno));
- }
- DllInterop.InitDll initDll = (DllInterop.InitDll)Marshal.GetDelegateForFunctionPointer(intPtrInitDll, typeof(DllInterop.InitDll));
- //InitDLL
- IsInitialized = initDll(string.Format("P={0}", PATH));
- if (!IsInitialized)
- {
- FreeLibrary();
- throw new Exception("PROC_InitDll returned FALSE.");
- }
- return true;
- }
- return false;
- }
- //This method is for the 2.Action
- public static CalcInfo TransferData(WebCalcInfo calcInfo)
- {
- if (!IsLoaded && !string.IsNullOrEmpty(PATH))
- {
- System.Diagnostics.Trace.WriteLine("Library was not loaded, start loading and init Dll.", "TransferData");
- LoadInitLibrary(PATH);
- }
- IntPtr intPtrTransfer = DllInterop.GetProcAddress(DllInterop.hModule, PROC_DllTransfer);
- if (intPtrTransfer == IntPtr.Zero)
- {
- int errno = Marshal.GetLastWin32Error();
- FreeLibrary();
- throw new Exception(string.Format("Process Address not found: PROC_DllTransfer is IntPtr.Zero. Error:{0}.", errno));
- }
- DllInterop.DllTransfer dllTransfer = (DllInterop.DllTransfer)Marshal.GetDelegateForFunctionPointer(intPtrTransfer, typeof(DllInterop.DllTransfer));
- bool transferResult = dllTransfer(ref Info); // HERE IT HANGS
- if (!transferResult)
- {
- FreeLibrary();
- throw new Exception("PROC_DllTransfer returned FALSE.");
- }
- }