具有链接dll的目标文件中的符号大写是否重要?

时间:2019-04-03 16:08:49

标签: matlab dll fortran gfortran mex

我正在尝试让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理解为同一符号,但是大写字母也有区别吗?

1 个答案:

答案 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系统上,其行为将有所不同(请参见herehere),甚至不同的编译器也会有不同的想法。

那么,这到底意味着什么?

这意味着当您编写类似以下的子例程调用时:

 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