问题
I'm trying to get the gfortran compiler working in MATLAB on Windows to create mex files. Gfortran isn't supported, but the Intel Fortran compiler is, which leads me to believe that a Fortran compiler should be able to compile Fortran source using MATLAB libraries.
As detailed in my previous question, I get an "undefined reference" error for every symbol that should come from the MATLAB libraries. I thought this was an error with the preprocessor not getting invoked as suggested in a question on MathWorks Answers, but after looking into this problem some more I don't believe that's the problem since the errors refer to things like "mxisnumeric800" which is a substitution made in the fintrf.h header.
I checked the symbols exported from the required libraries, libmx.dll and libmex.dll, using dumpbin. The exported symbols include two that are close to mxisnumeric800:
Section contains the following exports for libmx.dll
...
1431 596 0009F200 MXISNUMERIC800
...
1747 6D2 000ABC24 mxIsNumeric_800
...
I can understand why mxIsNumeric_800 wouldn't be read as the same symbol due to the extra underscore, but does capitalization make a difference too?
回答1:
The problem you are having is that Fortran is a case insensitive language. So if you have a subroutine foo
:
subroutine foo(x)
real :: x
end subroutine foo
you could call it with any of the following:
call foo(x)
call FOO(x)
call fOo(x)
When you build an object file or library with this function, the symbol name will be compiler dependent. In case of Gfortran on a Linux system, it will always downcase the symbol name and add an underscore behind it such as
foo_
On Windows Systems it will behave differently (see here and here), and even different compilers will have different ideas.
So what now, what does this all mean?
This means that when you write a subroutine call like:
call mxIsNumeric_800(arg1, arg2, arg3)
Gfortran will attempt to link it against a symbol mxisnumeric_800_
and not the symbol you expect. In the past, this often resulted into ugly hacks which were very not-portable. Fortran 2003, addressed this issue in a clear way by introducing the BIND
attribute. An attribute which allows the programmer to inform the compiler that this object should be handled as a non-Fortran object (cfr. Section 15.5 of the F2008 standard).
With this attribute, you can now define an interface that is fully understood by Fortran and that the compiler knows where to find the corresponding symbol with its respective case-sensitivity. Eg.
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
Some more details can be found here.
来源:https://stackoverflow.com/questions/55499662/does-symbol-capitalization-matter-in-object-files-with-a-linked-dll