我正在努力让gfortran代替Windows 10上用于MATLAB的英特尔Fortran编译器.GCC风格的名称修改,至少对于gfortran来说,是使符号名称全部小写并附加下划线; “mxIsNumeric800”变为mxisnumeric800_。为了让MATLAB识别符号,他们必须省略附加的下划线(简单,只需将-fno-underscoring
添加到编译器选项)并完全由大写字母数字字符组成(很难,但可能)。
我已经能够通过使用this answer中描述的方法解决此大小写问题,但我无法使导出的符号保持大写。以下是使用gfortran(dumpbin /exports timestwo.mexw64
的输出的一部分)编译的mex文件的导出符号:
ordinal hint RVA name
1 0 00001510 mexfilerequiredapiversion
2 1 000013E0 mexfunction
3 2 000013C0 timestwo
和使用英特尔Fortran编译器编译的相同文件:
ordinal hint RVA name
1 0 00001150 MEXFILEREQUIREDAPIVERSION
2 1 00001000 MEXFUNCTION
英特尔编译器通过链接器选项/EXPORT:FOO
处理导出,该选项使用两次,一次用于MEXFUNCTION,一次用于MEXFILEREQUIREDAPIVERSION。我尝试过使用.def文件
EXPORTS
MEXFUNCTION
MEXFILEREQUIREDAPIVERSION
但链接它(而不是.def文件与小写或camelcase符号)不会改变任何东西。我也尝试添加到我的链接器脚本:
EXTERN(MEXFUNCTION,MEXFILEREQUIREDAPIVERSION);
PROVIDE(mexfunction = MEXFUNCTION);
PROVIDE(mexfilerequiredapiversion = MEXFILEREQUIREDAPIVERSION);
但这并没有改变任何事情。
如何将这些符号修改为大写?
我已经解决了我遇到的具体问题,但解决方案并不令人满意(gfortran编译的mex文件仍会导致MATLAB崩溃)。
事实证明,有几种方法可以实现手动符号大写。其中一个,我认为不起作用,但后来发现,是BIND(C,NAME="")
。像subroutine mexfunction(nlhs, plhs, nrhs, prhs) bind(C,name="MEXFUNCTION")
这样的mex函数将生成一个可以导出的大写MEXFUNCTION符号。
另一种方法是在导出定义(.def)文件中对该符号进行别名。包含的文件
EXPORTS
MEXFUNCTION = mexfunction
MEXFILEREQUIREDAPIVERSION = mexfilerequiredapiversion
运行链接器时包含的内容也会导致导出所需的符号。这些都是这个问题的解决方案,即使它不是我试图解决的整体问题的解决方案。
使用这些方法中的任何一个都会导致mex函数在运行时崩溃MATLAB。当来自VCRUNTIME140.dll的memcpy
在mex函数的开头运行时发生崩溃,导致访问冲突。通过使用调试符号构建mex函数,我能够让MATLAB输出故障转储。
不幸的是,看起来还有更多让gfortran使用MATLAB而不仅仅是链接正确的库并使用正确的符号。