我正在尝试让gfortran编译器在Windows的MATLAB中运行以创建mex files。不支持Gfortran,但是支持Intel Fortran编译器,这使我相信Fortran编译器应该能够使用MATLAB库编译Fortran源代码。
如my previous question中所述,对于应该来自MATLAB库的每个符号,我都会收到“未定义引用”错误。我认为这是错误的,没有按照a question on MathWorks Answers中的建议调用预处理器,但是在研究了这个问题后,我不认为这是问题所在,因为错误涉及的是诸如“ mxisnumeric800”之类的东西。在fintrf.h标头中进行替换。
我使用dumpbin检查了从所需库libmx.dll和libmex.dll导出的符号。导出的符号包括两个与mxisnumeric800接近的符号:
Section contains the following exports for libmx.dll
...
1431 596 0009F200 MXISNUMERIC800
...
1747 6D2 000ABC24 mxIsNumeric_800
...
我可以理解,由于多余的下划线,为什么不能将mxIsNumeric_800理解为同一符号,但是大写字母也有区别吗?
答案 0 :(得分:3)
您遇到的问题是,在 敏感语言中,Fortran是区分大小写的。因此,如果您有子例程foo
:
subroutine foo(x)
real :: x
end subroutine foo
您可以使用以下任意一种来调用它:
call foo(x)
call FOO(x)
call fOo(x)
使用此功能构建目标文件或库时,符号名称将取决于编译器。如果在Linux系统上使用Gfortran,它将始终将符号名称小写并在其后添加下划线,例如
foo_
在Windows系统上,其行为将有所不同(请参见here和here),甚至不同的编译器也会有不同的想法。
那么,这到底意味着什么?
这意味着当您编写类似以下的子例程调用时:
call mxIsNumeric_800(arg1, arg2, arg3)
Gfortran将尝试将其链接到符号mxisnumeric_800_
,而不是您期望的符号。在过去,这通常会导致难看的骇客入侵,而且非常难以携带。 Fortran 2003通过引入BIND
属性以明确的方式解决了此问题。一个允许程序员通知编译器该对象应作为非Fortran对象处理的属性(cfr。Section 15.5 of the F2008 standard)。
使用此属性,您现在可以定义一个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
可以找到更多详细信息here。