Member 11254844 Ответов: 0

Выполнение библиотеки 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

К сожалению, вам нужно сделать некоторую отладку. Мы никак не можем догадаться, что происходит в вашем коде.

0 Ответов