Выполнение библиотеки DLL C из C# - fatalexecutionengineerror + accessviolationexception + код ошибки 0xc0000005.
//Define Code internal static class UnsafeMethods { [DllImport("kernel32.dll", SetLastError = true)] internal extern static IntPtr LoadLibrary(string libraryName); [DllImport("kernel32.dll", SetLastError = true)] internal extern static bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll", SetLastError = true)] internal extern static IntPtr GetProcAddress(IntPtr hModule, string procName); } public class Simulator : IDisposable { //Define Delegates. [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void PopulateInputsDelegate(int nbrInputArgs, double[] inp); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void GetOutputsDelegate(double[] inputArgs); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void LoadCalsDelegate(string outputFileName, string inputFileName, int writeOutputFile); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void InitializeMethods_Sim(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void TimeBasedEvent(); //Define Function Pointers. PopulateInputsDelegate PopulateInputs; GetOutputsDelegate GetOutputs; LoadCalsDelegate LoadCals; InitializeMethods_Sim funcInitializeMethods_Sim; TimeBasedEvent MngEPTR_EngineCycle; TimeBasedEvent MngEPTR_ExhTMP_12p5ms; TimeBasedEvent MngEPTR_ExhTMP_100ms; //Define Handles IntPtr dllHandle; IntPtr funcaddrPopulateInputs; IntPtr funcaddrGetOutputs; IntPtr funcaddrLoadCals; IntPtr funcaddrInitializeMethods_Sim; IntPtr funcaddrMngEPTR_ExhTMP_12p5ms; IntPtr funcaddrMngEPTR_ExhTMP_100ms; IntPtr funcaddrMngEPTR_EngineCycle; public void InitializeSimulator() { try { //Load this.dllHandle = UnsafeMethods.LoadLibrary(this.model.OutputDLLPath); if (dllHandle == IntPtr.Zero) { int errorCode = Marshal.GetLastWin32Error(); throw new Exception(string.Format("Failed to load library (ErrorCode: {0})", errorCode)); }; funcaddrPopulateInputs = UnsafeMethods.GetProcAddress(dllHandle, "PopulateInputs"); PopulateInputs = Marshal.GetDelegateForFunctionPointer(funcaddrPopulateInputs, typeof(PopulateInputsDelegate)) as PopulateInputsDelegate; funcaddrGetOutputs = UnsafeMethods.GetProcAddress(dllHandle, "GetOutputs"); GetOutputs = Marshal.GetDelegateForFunctionPointer(funcaddrGetOutputs, typeof(GetOutputsDelegate)) as GetOutputsDelegate; funcaddrLoadCals = UnsafeMethods.GetProcAddress(dllHandle, "LoadCals"); LoadCals = Marshal.GetDelegateForFunctionPointer(funcaddrLoadCals, typeof(LoadCalsDelegate)) as LoadCalsDelegate; funcaddrInitializeMethods_Sim = UnsafeMethods.GetProcAddress(dllHandle, "InitializeMethods_Sim"); funcInitializeMethods_Sim = Marshal.GetDelegateForFunctionPointer(funcaddrInitializeMethods_Sim, typeof(InitializeMethods_Sim)) as InitializeMethods_Sim; funcaddrMngEPTR_ExhTMP_12p5ms = UnsafeMethods.GetProcAddress(dllHandle, "_12p5Methods_Sim"); MngEPTR_ExhTMP_12p5ms = Marshal.GetDelegateForFunctionPointer(funcaddrMngEPTR_ExhTMP_12p5ms, typeof(TimeBasedEvent)) as TimeBasedEvent; funcaddrMngEPTR_ExhTMP_100ms = UnsafeMethods.GetProcAddress(dllHandle, "_100Methods_Sim"); MngEPTR_ExhTMP_100ms = Marshal.GetDelegateForFunctionPointer(funcaddrMngEPTR_ExhTMP_100ms, typeof(TimeBasedEvent)) as TimeBasedEvent; funcaddrMngEPTR_EngineCycle = UnsafeMethods.GetProcAddress(dllHandle, "_EngineCycle_Sim"); MngEPTR_EngineCycle = Marshal.GetDelegateForFunctionPointer(funcaddrMngEPTR_EngineCycle, typeof(TimeBasedEvent)) as TimeBasedEvent; } private void SimulateEventBasedGroup(MeasurementData inputMeasuredData) { // Log the method entry. Logger.Instance.Debug(Constants.FUNCTION_ENTERED_LOG); try { this.inputMeasuredData = new MeasurementData(); this.inputMeasuredData = inputMeasuredData; ////Load Cals //this.LoadCals.Invoke(this.GetCalsArray()); int rowCount = this.inputMeasuredData.SignalGroup.RowCount; //Load Data & execute EngineCycle for (rowIndex = 0; rowIndex < rowCount; rowIndex++) { this.PopulateInputs.Invoke(this.xSignals.Count, this.GetInputMeasuredSignalArray()); //Execute Engine Cycle this.MngEPTR_EngineCycle.Invoke(); //MngEPTR_EngineCycle - C code method giving exception - Help needed this.SetOutputMeasurementData(); //this.SetEngineCycleOutput(); } } catch { } } }
Exceptions caught - Managed Debugging Assistant 'FatalExecutionEngineError' has detected a problem in 'C:\Application.exe'. Additional Information: The runtime has encountered a fatal error. The address of the error was at 0x719a9a14, on thread 0x2f84. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack. Sometimes I get : 1.) First chance execption at a 0x********. Access Violation Written Location 0x*****. 2.) R6013 - Attempt to initialize the CRT more than once. Please help me in resolving the issue on urgent basis. Thanks in advance.
Что я уже пробовал:
Попробовал включить неуправляемый код debug & GC.Clear. Не знаю, что еще попробовать.
Richard MacCutchan
Сначала вам нужно выяснить, где происходит ошибка. Как только у вас есть это, вы можете поймать его в отладчике и посмотреть на стек и другие переменные, чтобы узнать, что происходит. Один комментарий, который я бы сделал, заключается в том, что вы не проверяете ни одно из возвращаемых значений из ваших вызовов GetProcAddress
, поэтому всегда возможно, что один из них возвращает нулевой или недопустимый адрес.
Member 11254844
Большое спасибо за ответ.
Я получаю ошибку в -
// Выполнить Цикл Двигателя
этот.MngEPTR_EngineCycle.Взывать();
этот.MngEPTR_EngineCycle определен в коде C, другие методы кода C работают хорошо, только это дает исключение.
Кроме того, нет возвращаемых значений из всех методов. Все они являются типами возвращаемых значений void.
Richard MacCutchan
Ну, на первый взгляд я бы сказал, что либо указатель функции равен нулю, либо код в самой функции имеет ошибку. Но единственный способ узнать это-использовать отладчик для отслеживания кода.
Member 11254844
Привет Ричард,
Я попытался исправить все входные данные, заданные методом C-кода. Но теперь передо мной стоит несколько другая тема.
Получение ExecutionEngineException, которое я не могу проследить, откуда оно идет.
Иногда она исходит от системы.Рисование, иногда из Mscordlib. Не знаю точной причины.
Richard MacCutchan
Извините, отсюда невозможно догадаться.
Member 11254844
Я пытался :
IntPtr funcaddrMngEPTR_EngineCycleTemp = Маршал.Аллохглобал(UnsafeMethods.GetProcAddress(dllHandle, " _EngineCycle_Sim"));
А получил - {"недостаточно памяти для продолжения выполнения программы."} из библиотеки mscorlib &ампер; трассировка стека говорит, что " в системе.Во время выполнения.InteropServices.Маршал.AllocHGlobal(IntPtr cb)".
Есть идеи, что еще я могу попробовать?
Richard MacCutchan
К сожалению, вам нужно сделать некоторую отладку. Мы никак не можем догадаться, что происходит в вашем коде.