Ошибка сегментации при повторном вызове функции C из Fortran

У меня есть программа на Fortran 90, которая неоднократно вызывает функцию C. При первом использовании функции все идет хорошо, но при второй попытке кода получить доступ к функции выдается следующая ошибка:

Программа получила сигнал SIGSEGV: ошибка сегментации — неверная ссылка на память.

Я использую gfortran v.4.6 в Windows, ссылаясь на библиотеку, для которой у меня нет исходного кода. Библиотека пришла ко мне в виде DLL, и я использовал gendef и dlltool для создания библиотеки .a для ссылки на нее.

Код выглядит так:

PROGRAM cmod
  USE, INTRINSIC :: ISO_C_BINDING
  INTERFACE
    LOGICAL (C_BOOL) FUNCTION clover(scen,reg,soil,top,rain,depth,numd,nums,numb, numd,addn,srate,stype,nloss,ploss,ErrStr) BIND (C, name = "ClOvr")

    USE, INTRINSIC :: ISO_C_BINDING
    INTEGER (C_INT), INTENT(IN), VALUE :: scen,reg,soil,topo,depth

    REAL (C_DOUBLE), INTENT(IN), VALUE :: rain,numd,nums,numb,numd

    REAL (C_DOUBLE), INTENT(IN), VALUE :: addn,srate
    INTEGER (C_INT), INTENT(IN), VALUE :: stype
    REAL (C_DOUBLE), INTENT(OUT) :: nloss,ploss
    CHARACTER(C_CHAR), INTENT(OUT) :: ErrStr(*)
    END FUNCTION clover
  END INTERFACE
  .....

  do
  .....
    result = clover(a,b,c, d, e, f, g, h, sb, sd, an, sr, st,lossx,lossy,err)
  ......
    result = clover(a,b,c, d, e, f, g, h, sb, sd, an, sr, st,lossx,lossy,err)
  end do
END PROGRAM cmod

У меня нет кода C, но я переношу с IBM Fortran.

Объявление интерфейса содержит эти две строки

!DEC$ ATTRIBUTES  VALUE :: scen,reg,soil,top,rain,depth,numd,nums,numb,numd,addn,srate,stype

!DEC$ ATTRIBUTES  REFERENCE :: lossx,lossy,ErrStr

Фортран IBM использует следующий код для загрузки библиотеки и доступа к функции:

pointer (q,clover)
p = loadlibrary("clover.dll")
q = getprocaddress(p, "ClOvr")

Так что я мог что-то упустить в переводе на GNU fortran


person Gabriella Turek    schedule 21.06.2012    source источник
comment
Должно быть, функция C потерпела крах. Но вы не предоставляете никакой информации, которая помогла бы понять, почему.   -  person ugoren    schedule 21.06.2012
comment
предоставление функции C поможет. проверьте код вокруг переменных, вы можете найти там ошибку/исправление.   -  person RoyalJai    schedule 21.06.2012
comment
Как вы получаете SIGSEGV в Windows? Вы получили дамп ядра?   -  person cdarke    schedule 21.06.2012
comment
@cdarke, на удивление, SIGSEGV поддерживается библиотекой Windows CRT, см. здесь, хотя в самой старой доступной версии документации (VS .NET 2003) написано, что SIGSEGV предназначено только для совместимости, но все же может быть сгенерировано raise().   -  person Hristo Iliev    schedule 21.06.2012
comment
@Hristo lliev: удивительно, я ожидал, что старое доброе исключение 0xC0000005. Я предполагал, что это Linux, работающий на виртуальной машине, хорошо, что я не предложил strace. ;-)   -  person cdarke    schedule 21.06.2012
comment
@cdrake, я так же шокирован, как и вы :) Я даже проверил это с помощью простой программы, которая разыменовывает неинициализированный указатель в режиме выпуска - похоже, что CRT переводит EXC_BAD_ACCESS в SIGSEGV, если установлен обработчик сигнала.   -  person Hristo Iliev    schedule 21.06.2012
comment
смешивание C++ и FORTRAN содержит некоторую информацию о вызове C++ из FORTRAN и как указать соглашение о вызовах для аргументов. также вызов C из FORTRAN.   -  person Richard Chambers    schedule 22.06.2012
comment
@cdarke Я работаю в cygwin, и дампа ядра нет.   -  person Gabriella Turek    schedule 22.06.2012


Ответы (1)


Я нашел свою проблему: когда я компилирую, я должен использовать -mrtd (sdtcall)

person Gabriella Turek    schedule 22.06.2012