Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/15: Рейтинг темы: голосов - 15, средняя оценка - 5.00
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57

Вызов dll Delphi из C#

30.01.2018, 16:59. Показов 3125. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Почему выскакивает ошибка An unhandled exception of type 'System.StackOverflowException'
если убрать один массив то все нормально но как только пишу три массива сразу ошибка
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uses
  SysUtils,
  Classes,
  Dialogs;
 
type
  Tr = array[0..50000] of real;
  Ta = array[0..2000] of Integer;
{$R *.res}
 
procedure calculateCoefficients(alphah:Tr;alpha_ver:Tr;alphah_ver:Tr);stdcall;
begin
end;
exports calculateCoefficients;
begin
end.
вызов из c#
C#
1
2
3
4
5
6
7
8
9
10
11
 
[DllImport(DllName, EntryPoint = "calculateCoefficients", CallingConvention = CallingConvention.StdCall)]
public static extern void calculateCoefficients(double[] alphah, double[] alphaVer, double[] alphahVer);
 
 void FastPhases()
  {
    double[] alphah = new double[50000];
    double[] alphaVer = new double[50000];
    double[] alphahVer = new double[50000];
    calculateCoefficients(alphah, alphaVer, alphahVer);
  }
Добавлено через 43 минуты
Ну вроде разобрался размер стека слишком мал его можно увеличить создав новый поток

C#
1
2
Thread T = new Thread(FastPhases, 1200000);
T.Start();
но тогда выскакивает помощник
C#
1
Additional information: A call to PInvoke function 'WpfApplication8!WpfApplication8.MainWindow::calculateCoefficients' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.01.2018, 16:59
Ответы с готовыми решениями:

Вызов функции из DLL, написанной на Delphi
Здрасте, У меня тут такая ситуация: Рыскал как то я, по просторам интернета, решение 1 проблемы, а именно: рисование своего GUI поверх...

Вызов dll на Delphi из C#
Здравствуйте! Я понимаю, что проблема старая, я много прочитал по этому поводу, но ничего не помогает. Есть кусок программы на дельфях ...

Экспорт функций из dll на c++ и вызов из Delphi
Вызываю экспортируемую функцию из dll которая написана на c++. Вызываю из Delphi, с вызовом проблем нет но когда оно принимает мою строку...

13
 Аватар для RaevskiAnatoly
34 / 35 / 12
Регистрация: 04.03.2017
Сообщений: 444
30.01.2018, 21:41
А стек вызовов перед возбуждением исключения предоставить можешь?
0
.NET senior
 Аватар для bax_tang
441 / 359 / 137
Регистрация: 23.09.2016
Сообщений: 980
30.01.2018, 23:17
xmaksasx, ларчик открывается очень просто - в Pascal индексы массивов находятся в тех границах, которые Вы самостоятельно им указываете (по умолчанию обе границы включаются в индекс, в качестве нижней границы устанавливается единица - это если следовать гайдлайнам).

Догадываетесь, к чему я веду? при указании
Pascal
1
2
type
  Tr = array[0..50000] of real;
фактический размер массива составляет 50001 элемент, а Вы из C# пытаетесь через маршалинг передать в процедуру массив из 50000 элементов. Неудивительно, что это разбалансирует стэк.

Вариантов решения проблемы три:

1. указать в Pascal для границ массива значения 1..50000
2. указать в Pascal для границ массива значения 0..49999
3. передавать из C# массивы длиной 50001 элемент

Добавлено через 5 минут
Код на Pascal

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
library Computations;
 
uses SysUtils, Classes, Dialogs;
 
type
    Tr = array[1..50000] of real;
    Ta = array[1..2000] of Integer;
 
procedure CalculateCoefficients(alpha_h: Tr; alpha_ver: Tr; alpha_h_ver: Tr); stdcall;
begin
end;
 
exports CalculateCoefficients;
begin
end.

Код на C#

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
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
 
namespace DelphiInteraction
{
 
    public class EntryPoint
    {
        [STAThread]
        internal static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionOccured;
 
            Thread th = new Thread(RunCoefficientsCalculation, 1200000);
            th.Start();
 
            Console.ReadKey(true);
        }
 
        [STAThread]
        private static void RunCoefficientsCalculation()
        {
            var alpha_h = new double[50000];
            var alpha_ver = new double[50000];
            var alpha_h_ver = new double[50000];
 
            try
            {
                CoefficientsComputation.CalculateCoefficients(alpha_h, alpha_ver, alpha_h_ver);
 
                    Console.WriteLine("Completed successfully");
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
            }
        }
 
        private static void UnhandledExceptionOccured(object sender, UnhandledExceptionEventArgs args)
        {
            Console.WriteLine(args.ExceptionObject);
 
            if (args.IsTerminating)
                Environment.Exit(((Exception)args.ExceptionObject).HResult);
        }
    }
 
    public static class CoefficientsComputation
    {
        private const string AssemblyName = "Coefficients.dll";
 
        [DllImport(AssemblyName, CallingConvention = CallingConvention.StdCall)]
        public static extern void CalculateCoefficients(double[] alpha_h, double[] alpha_ver, double[] alpha_h_ver);
    }
}
1
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
31.01.2018, 09:50  [ТС]
Интересно сейчас попробую, но к сожалению dll нет возможности исправить, потому как в работе используется dll написанная не мной, тут в куске кода я просто привел пример

Добавлено через 1 час 4 минуты
C#
1
2
3
4
5
6
7
    [Managed to Native Transition]  
>   WpfApplication8.exe!WpfApplication8.MainWindow.CalcCoef() Line 167  C#
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)    Unknown
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()    Unknown
Добавлено через 35 секунд
bax_tang, все равно вылетает

Добавлено через 11 минут
Странно что с dll которую я привожу для примера все работает нормально, а с dll которую мне прислали это не работает может попросить что бы там соглашение поменяли с stdcall на cdecl? я ради интереса пробовал изменить в своей dll соглашение на cdecl а в C# оставить stdcall выскакивает точно такая же ошибка.
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
31.01.2018, 11:02
Цитата Сообщение от bax_tang Посмотреть сообщение
Неудивительно, что это разбалансирует стэк
вообще то это приведет к исключению типа Access Violation, а не разбалансировке стека.

Добавлено через 13 минут
А ларчик, кстати, открывается еще проще, если я всё правильно помню.
вот такие массивы в делфи передаются по значению
Delphi
1
2
3
type
  Tr = array[0..50000] of real;
  Ta = array[0..2000] of Integer;
Именно по этому происходит stackoverflow в первом случае, т.к. функция принимает аргументов на 50001 * 8 + 2001 * 4 (sic!) байт. Соответственно функция на возврате почистит стек от 50001 * 8 + 2001 * 4 байт, что и приведет к stackoverflow.
А во втором случае, на возврате сделает тоже самое, но размер стека уже достаточен, и проблемы не будет. Но будет эта самая разбалансировка - ведь вы передаете 12 байт аргументов через стек (размер указателя * 3), а функция ожидает намного больше.


Что бы этого не было, писать надо так
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uses
  SysUtils,
  Classes,
  Dialogs;
 
type
  Tr = array of real;
  Ta = array of Integer; 
{$R *.res}
 
procedure calculateCoefficients(alphah:Tr; alphahLength:Integer; alpha_ver:Tr; alpha_verLength: Integer; alphah_ver:Tr; alphah_verLength: Integer);stdcall;
begin
end;
exports calculateCoefficients;
begin
end.
C#
1
2
3
4
5
6
7
8
9
10
[DllImport(DllName, EntryPoint = "calculateCoefficients", CallingConvention = CallingConvention.StdCall)]
public static extern void calculateCoefficients(double[] alphah, int alphahLength, double[] alphaVer, int alphaVer, double[] alphahVer, int alphahVer);
 
 void FastPhases()
  {
    double[] alphah = new double[50000];
    double[] alphaVer = new double[50000];
    double[] alphahVer = new double[50000];
    calculateCoefficients(alphah, alphah.Length, alphaVer, alphaVer.Length, alphahVer, alphahVer.Length);
  }
0
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
31.01.2018, 11:13  [ТС]
jr_, может и так надо писать но нет возможности исправить dll не я ее писал, из исходного кода все что у меня есть я привел в примере
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
31.01.2018, 11:16
а на dll можно глянуть ?
0
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
31.01.2018, 11:22  [ТС]
dll.rar
0
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
31.01.2018, 11:26  [ТС]
jr_, сомневаюсь что это хоть как то облегчит задачу, там на вход 22 параметра

Добавлено через 3 минуты
Pascal
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
type
  Tr = array[0..50000] of real;
  Ta = array[0..2000] of Integer;
 
 
procedure calculateCoefficients(
var cef:real;
var cef_ver:real;
oa:real;
ow:real;
n:integer;
ps:Ta;
nt:Integer;
t:Tr;
alpha:Tr;
alphah:Tr;
alpha_ver:Tr;
alphah_ver:Tr;
w:Tr;
we:Tr;
w_ver:Tr;
we_ver:Tr;
var av_w:Tr;
var av_w_ver:Tr;
var alpha_com_max:real;
var alpha_com:Tr;
var alpha_argum_sin:Tr;
var alpha_argum_cos:Tr);stdcall;
begin
end;
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
31.01.2018, 13:54
Лучший ответ Сообщение было отмечено xmaksasx как решение

Решение

что то я видимо обманул про передачу по значению, всё немного по другому, но суть та же.

тут уже оказалось 22 параметра вместо 3х
но всё равно что то не договариваете - в вашем определении процедуры всего 22 аргумента на 0x60 байт а в dll функция принимает 0x68 байт (судя по всему, 24 аргумента).
1
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
31.01.2018, 14:58  [ТС]
jr_, этот кусок кода мне скинули как описание, может потому и ошибка выскакивает что передача параметров неверная

Добавлено через 52 минуты
jr_, спасибо за помощь реально ошиблись в описании вот скинули правильный, как Вы и сказали 24 параметра
Pascal
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
procedure calculateCoefficients(
var cef:real;
var cef_ver:real;
oa:real;
ow:real;
n:integer;
ps:Ta;
nt:Integer;
t:Tr;
var alpha:Tr;
var alphah:Tr;
var alpha_ver:Tr;
var alphah_ver:Tr;
var w:Tr;
var we:Tr;
var w_ver:Tr;
var we_ver:Tr;
var av_w:Tr;
var av_w_ver:Tr;
var alpha_com_max:real;
var alpha_com:Tr;
var alpha_argum_sin:Tr;
var alpha_argum_cos:Tr;
var gain:Tr;
var gain_all:real); stdcall;
объясните пожалуйста как Вы узнали какой размер принимает функция очень интересно и очень полезно
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
31.01.2018, 20:09
xmaksasx, в дизасемблере глянул.
0
8 / 8 / 5
Регистрация: 15.08.2011
Сообщений: 57
01.02.2018, 07:46  [ТС]
jr_, Ida подходит для этого?
0
139 / 139 / 53
Регистрация: 14.06.2016
Сообщений: 467
01.02.2018, 10:56
вполне
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.02.2018, 10:56
Помогаю со студенческими работами здесь

Реализовать вызов dll, написанной на Delphi, в C++
Приветствую! Только недавно наал изучать dll и не очень понимаю почему вылезает ошибка в коде. Что нельзя выполнить библиотеку с1хх Вот...

Вызов функции из dll написанной на delphi из python
Импортировал ctypes, подключился к dll. Есть например такая функция: function GetStatusCardReader(var StatusCardReader: Word):...

Вызов функции из dll. Dll не определена в коде и подключается программно
Я написал простую функцию которая возвращает негатив bitmap'а Function Negative(ByVal Bmp As Bitmap) Dim Bmp2 As New...

Inject dll, а также вызов функции из этой же dll
Всем привет, заинжектить dll в другой процесс получилось, но еще необходимо вызвать функцию в этой длл, каким образом это реализовать? ...

Вызов Dll-фий в другой Dll
не получается дернуть dll в другой dll. Подскажите, как должен происходить вызов dll1 в dll2 ? (псевдокод) dll1.cpp { int...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru