Имеет ли значение заглавная буква символа в объектных файлах со связанной DLL? - PullRequest
1 голос
/ 03 апреля 2019

Я пытаюсь заставить компилятор gfortran работать в MATLAB под Windows для создания mex файлов .Gfortran не поддерживается, но есть компилятор Intel Fortran, который позволяет мне полагать, что компилятор Fortran должен иметь возможность компилировать исходный код Fortran с использованием библиотек MATLAB.

Как подробно описано в мой предыдущий вопрос Я получаю ошибку «неопределенная ссылка» для каждого символа, который должен прийти из библиотек MATLAB.Я думал, что это ошибка из-за того, что препроцессор не вызывался, как предложено в вопросе на MathWorks Ответы , но после более подробного изучения этой проблемы я не верю, что это проблема, поскольку ошибки относятся к таким вещам, как«mxisnumeric800» - это замена, сделанная в заголовке fintrf.h.

Я проверил символы, экспортированные из необходимых библиотек, libmx.dll и libmex.dll, используя dumpbin.Экспортируемые символы включают два, близкие к mxisnumeric800:

  Section contains the following exports for libmx.dll
...
       1431  596 0009F200 MXISNUMERIC800
...
       1747  6D2 000ABC24 mxIsNumeric_800
...

Я могу понять, почему mxIsNumeric_800 не будет считываться как один и тот же символ из-за дополнительного подчеркивания, но капитализация тоже имеет значение?

1 Ответ

3 голосов
/ 03 апреля 2019

Проблема, с которой вы столкнулись, состоит в том, что Fortran - это регистр на языке, чувствительном к регистру.Поэтому, если у вас есть подпрограмма foo:

subroutine foo(x)
  real :: x
end subroutine foo

, вы можете вызвать ее с помощью любого из следующих действий:

call foo(x)
call FOO(x)
call fOo(x)

Когда вы создаете объектный файл или библиотеку с помощью этой функции,имя символа будет зависеть от компилятора.В случае Gfortran в системе Linux, он всегда будет указывать имя символа в нижнем регистре и добавлять подчеркивание, например

foo_

В системах Windows он будет вести себя по-другому (см. здесь и здесь ), и даже разные компиляторы будут иметь разные идеи.

Так что же теперь, что все это значит?

Это означает, что когдавы пишете вызов подпрограммы, например:

 call mxIsNumeric_800(arg1, arg2, arg3)

Gfortran попытается связать его с символом mxisnumeric_800_, а не с символом, который вы ожидаете.В прошлом это часто приводило к уродливым взломам, которые были очень непереносимы.В Fortran 2003 эта проблема решена путем введения атрибута BIND.Атрибут, который позволяет программисту сообщать компилятору, что этот объект должен обрабатываться как не-Fortran-объект (см. раздел 15.5 стандарта F2008 ).

С помощью этого атрибута вы теперь можете определить интерфейс, который полностью понят Fortran и что компилятор знает, где найти соответствующий символ с соответствующей чувствительностью к регистру.Например,

interface
   subroutine mxisnumeric(arg1,arg2,arg3) BIND(C, NAME="mxIsNumeric_800")
      use, intrinsic :: iso_c_binding
      implicit none
      real(c_float) :: arg1
      integer(c_int) :: arg2
      character(c_char) :: arg3
   end subroutine mxisnumeric
end interface

Более подробную информацию можно найти здесь .

...