1

使用 Windows 7、Matlab R2011a(32 位)和 Open Watcom 版本 1.8,我正在尝试编译调用 Fortran 代码的 C MEX 文件。

按照 Matlab 网站(支持链接)上发布的说明,我首先使用以下命令编译了 Fortran 目标文件:

wfl386 -c -fpi87 -SC getqpf.f

然后我尝试将目标文件链接到许多 C 文件。所有 C 文件都能正确编译,但我收到以下链接错误。未定义的引用用于 C 文件中从getqpf.f. 例如,QESTM在其中一个 C 文件中定义为函数,如int qestm_().

q_estimate.c文件包含 MEX 程序的入口点函数。这个想法是让入口点函数调用getqpf.f. 中的子例程getqpf.f调用其他文件中的 C 代码函数。

我怎样才能摆脱未定义的引用?

>> mex q_estimate.c paul2.c paul2_L1.c paul6.c paul6_L1.c runavg.c fit_slope.c getqpf.obj
Open Watcom Linker Version 1.8 
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved. 
Source code is available under the Sybase Open Watcom Public License. 
See http://www.openwatcom.org/ for details. 
loading object files 
searching libraries 
Error! E2028: QESTM is an undefined reference 
Error! E2028: QESTM1 is an undefined reference 
Error! E2028: QESTF is an undefined reference 
Error! E2028: QESTF1 is an undefined reference 
creating a Windows NT dynamic link library 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTM 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTM1 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTF 
file getqpf.obj(E:\DEVELOPMENT-FINAL\EXPERIMENTS\test-Q-analysis\getqpf.f): undefined symbol QESTF1 
  C:\PROGRA~2\MATLAB\R2011A~1\BIN\MEX.PL: Error: Link of 'q_estimate.mexw32' failed. 
4

2 回答 2

1

由于 C 的命名区分大小写,您是否尝试过将函数定义为int QESTM_()而不是int qestm_()

于 2012-11-12T17:53:42.677 回答
1

只是为了完整起见:Open Watcom F77 程序员指南(可在此处获得)指定:

默认符号命名约定因编译器而异。在编译过程中,Watcom C/C++ 将下划线字符添加到变量名称的开头,并将下划线添加到函数名称的末尾。Watcom FORTRAN 77 将符号转换为大写。辅助编译指示可用于解决这种不一致。

然后,该文档继续解释如何使 Watcom C/C++ 编译器对外部符号执行相同的转换,以便 C 代码可以调用 Fortran 例程,以及使 Fortran 代码的外部符号类似于 C,所以Fortran 代码可以调用 C 例程。尚不清楚该机制是否可以反向工作,即强制以特定情况导出 Fortran 例程符号。

为此,您可以使用特殊的编译指示,它可用于处理外部符号获取的情况:

*$pragma aux cname "!_"

其中cname是外部符号的名称,在您的 C 代码中定义。"!_"告诉编译器使用带有下划线的小写版本的名称(这假定 C 文件是使用 Open Watcom C/C++ 编译器编译的)。如果 C 编译器不附加下划线,那么您应该使用"!"。因此,如果将以下内容添加到 Fortran 代码中,则可能不需要在 C 代码中使用大写名称:

*$pragma aux qestm "!_"
*$pragma aux qestm1 "!_"
*$pragma aux qestf "!_"
*$pragma aux qestf1 "!_"

也可以像这样指定外部名称:

*$pragma aux qestm "qEsTm_"

或者

*$pragma aux qestm "qEsTm"

取决于 C 编译器是否添加下划线。然后 Fortran 代码将引用(or )qestm的有趣名称下的符号。当然,您必须使用C 函数的名称。这里的重点是引号内的名称保留了大小写。qEsTm_qEsTmqEsTm

于 2012-11-12T20:02:29.273 回答