Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
298 / 260 / 108
Регистрация: 26.10.2012
Сообщений: 810

Вызов неуправляемого метода крашит программу

22.04.2025, 13:39. Показов 2642. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Есть внешняя библиотека загружаемая через DllImport. Она работает нестабильно: при определенных входных данных приложение зависает или прекращает работу. Иногда она то зависает, то работает нормально на одних и тех же данных.
Но мне все равно очень хочется использовать эту библиотеку.
Я пробовал вызывать этот метод в асинхронном Task. Пробовал создавать отдельный поток с этим методом, ждать 5 секунд и потом вызывать Thread.Kill в случае зависания. Не помогает: иногда случаются зависания метода, и это убивает все приложение.
Есть идея написать отдельное консольное приложение и вызывать его через сторонний Process, но это звучит как-то совсем жестко.
Есть идеи как работать с проблемной зависающей внешней библиотекой без вылета всего приложения?

На всякий случай мой код.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public static OutputData Compute(InputData input)
{
    var output = OutputData.Empty();
    SetDllDirectory(Path.Combine(Directory.GetCurrentDirectory(), "DLL"));
    var libraryHandle = LoadLibrary("ErgDll");
    var pAddressOfFunctionToCall = GetProcAddress(libraryHandle, "newObjectC");
    var newObjectCHandler = Marshal.GetDelegateForFunctionPointer<NewObjectCHandler>(pAddressOfFunctionToCall);
    pAddressOfFunctionToCall = GetProcAddress(libraryHandle, "getArgsAddresC");
    var getArgsAddresCHandler = Marshal.GetDelegateForFunctionPointer<GetArgsAddresCHandler>(pAddressOfFunctionToCall);
    pAddressOfFunctionToCall = GetProcAddress(libraryHandle, "DoErgC");
    var doErgCHandler = Marshal.GetDelegateForFunctionPointer<DoErgCHandler>(pAddressOfFunctionToCall);
    pAddressOfFunctionToCall = GetProcAddress(libraryHandle, "getResultsAddresC");
    var getResultsAddresCHandler = Marshal.GetDelegateForFunctionPointer<GetResultsAddresCHandler>(pAddressOfFunctionToCall);
    pAddressOfFunctionToCall = GetProcAddress(libraryHandle, "delObjectC");
    var delObjectCHandler = Marshal.GetDelegateForFunctionPointer<DelObjectCHandler>(pAddressOfFunctionToCall);
 
    var pI = IntPtr.Zero;
    try
    {
        pI = newObjectCHandler();
        if (pI == IntPtr.Zero)
        {
            output.error = "Error in newObject()";
            return output;
        }
 
        var pAdd = getArgsAddresCHandler(pI);
        if (pAdd == IntPtr.Zero)
        {
            output.error = "Error in getArgsAddresC(...)";
            return output;
        }
 
        input.WriteInput(pAdd);
 
        Debug.WriteLine("Enter method");
        //собственно вот этот злосчастный метод типа Func<int, IntPtr> на котором все висит
        var result = doErgCHandler(pI);
        Debug.WriteLine("Exit Method");
 
        const int TMIN_FLAG = 1947000000;
        if (result == 0) // O'key
        {
            var resAddress = getResultsAddresCHandler(pI);
            if (resAddress == IntPtr.Zero)
            {
                output.error = "Некорректный getArgsAddresC";
                return output;
            }
            output = new OutputData(input, resAddress);
            return output;
        }
        else if (TMIN_FLAG < result) // Заданное время хода T меньше минимального Tmin
        {
            result -= TMIN_FLAG;
            output.error = $"Время хода T меньше минимального Tmin на {result} сек";
            return output;
        }
        else
        {
            output.error = $"Неизвестный результат: {result}";
            return output;
        }
    }
    catch (Exception e)
    {
        output.error = e.ToString();
        return output;
    }
    finally
    {
        if (pI != IntPtr.Zero)
        {
            delObjectCHandler(pI);
            FreeLibrary(libraryHandle);
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.04.2025, 13:39
Ответы с готовыми решениями:

Вызов метода(делегата) из неуправляемого кода
Есть способ передать адрес делегата в неуправляемый код как адрес функции, кто нибудь решил эту...

Вызов неуправляемого кода из длл
Замучался с маршилингом! Есть функция в длл: RetCode = HMM_Path_Init( char *path ); RetCode –...

Вызов CLI C++ из неуправляемого кода Native C++
Тема наверное ходовая, но в инете не нашёл рабочего варианта. Суть в том, чтобы из неуправляемого...

22
152 / 136 / 29
Регистрация: 02.07.2013
Сообщений: 996
26.04.2025, 09:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от jetyb Посмотреть сообщение
Ну объясните как pin-ить IntPtr, я нигде примеров не видел.
если указатель пришел из неуправляемого кода то его пинить, вроде бы, не надо. а почему вы перестали рассматривать вариант запуска в отдельном приложении неуправляемого кода?
0
298 / 260 / 108
Регистрация: 26.10.2012
Сообщений: 810
26.04.2025, 17:27  [ТС]
golosalex, Потому что по мне метод с отдельным процессом видится адски костыльным и ресурсоемким, я его отложил на крайний случай. Пока вызов GC.Collect перед неуправляемым кодом и запрет на одновременный вызов метода в разных потоках вроде как решили проблему. Иногда код возвращает error, но уже не крашится на моем компьютере
0
152 / 136 / 29
Регистрация: 02.07.2013
Сообщений: 996
26.04.2025, 20:55
Цитата Сообщение от jetyb Посмотреть сообщение
golosalex, Потому что по мне метод с отдельным процессом видится адски костыльным и ресурсоемким, я его отложил на крайний случай
метод можно завернуть в подобие службы, то есть написать немного плюсового кода, который бы ожидал прихода данных и выполнял бы для них вызов метода изолировано, а после отправлял бы результат обратно. тогда не будет расходов на пересоздание процесса. а о производительности лучше беспокоиться уже после того как код заработал стабильно. я конечно не настаиваю, но вроде бы такой подход с выносом части неудобного функционала в отдельный процесс более-менее общепринят в обществе и никто за такое не осуждает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.04.2025, 20:55

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что...

преобразование ref byte в byte[] или в IntPtr без использования неуправляемого кода
есть COM интерфейс с методом: virtual /* */ HRESULT STDMETHODCALLTYPE OnReceivePacket( ...

опасности неуправляемого кода
какие опасности несет в себе неуправляемый код. На ум приходит только назначение переменным...

Запуск неуправляемого кода внутри кода c#
часто требуется при выполнении программы запускать исполняемые файлы (exe) с ключами. Для этого...

Быстродействие управляемого и неуправляемого кода
начал изучать небезопасный код,написал прогу в ней 2 функции одна с управляемым кодом вторая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru