Исключение переполнения стека, вызывающее библиотеку Fortran dll из C # - PullRequest
3 голосов
/ 16 декабря 2010

У меня есть существующая программа VB6, которая вызывает библиотеку Fortran dll со следующим определением:

Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Integer

Мы находимся в процессе миграции приложения VB6 на C # (.net 4.0), и определение теперь таково:

[DllImport("BackEndLib2.dll", EntryPoint = "_START@0")]
public static extern short START();

Однако, когда я вызываю тот же самый вызов функции в c #, он выполняет вызов dll, успешно возвращается к управляемому коду и через некоторое время выдает исключение переполнения стека.

Я также попробовал тот же вызов DLL в VB.net с тем же результатом:

Declare Function START Lib "BackEndLib2.dll" Alias "_START@0" () As Short

Есть идеи, почему один и тот же вызов функции вызывает исключение переполнения стека в .NET 4.0, но успешно работает в vb6?

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

Редактировать: Кажется, это проблема только в WPF, и если я создаю тот же пример в Windows Forms, он не падает.

Ответы [ 2 ]

2 голосов
/ 16 декабря 2010

Ваше объявление [DllImport] эквивалентно оператору объявления VB6.Вероятно, лучше всего предположить, что декларация VB6 была неправильной, чтобы начать с того, что вам это не повезло.Тип возврата довольно странный, но это не может вызвать проблемы со стеком, поскольку возвращаемое значение передается через регистр ЦП, а не через стек.

Начните диагностировать это с помощью Debug + Windows + Registers.Обратите внимание на значение ESP до и после звонка.Если это не то же самое, тогда у вас действительно есть проблема с объявлением, и множество вызовов этой функции может разрушить стек.Маловероятно, кстати, это обычно генерирует предупреждение MDA.Если он совпадает, то это может быть только код Fortran, который переполняет стек.

Также имейте в виду, что вы можете обвинять не ту функцию.Функция, которая генерирует SOE, может быть не той, что испортила стек.Если посмотреть на значение ESP, вы сможете быстро найти источник проблем.

0 голосов
/ 16 декабря 2010

Мой опыт сказал бы, что если у вас есть декларация FORTRAN, например:

        INTEGER*4 FUNCTION START( )
CDEC$ATTRIBUTES STDCALL, DLLEXPORT :: START
C.....  BODY HERE
        ENDFUNCTION

Возможно, вам стоит попробовать следующее:

[DllImport(..., CallingConvention = CallingConvention.StdCall)]
public static extern int Start( );

Из любопытства, какой компилятор FORTRAN сгенерировал эту DLL? Вы указали, что он должен быть экспортирован как STDCALL? Возможно, вам также придется изменить соглашение о вызовах на C.

...