1

Windows 7、Matlab R2011a (32 ビット)、および Open Watcom バージョン 1.8 を使用して、Fortran コードを呼び出す C MEX ファイルをコンパイルしようとしています。

Matlab の Web サイト (サポート リンク) に投稿された指示に従って、次のコマンドを使用して Fortran オブジェクト ファイルをコンパイルしました。

wfl386 -c -fpi87 -SC getqpf.f

次に、オブジェクト ファイルをいくつかの C ファイルにリンクしようとしました。C ファイルはすべて正しくコンパイルされますが、次のリンク エラーが表示されます。未定義の参照は、 のサブルーチンから呼び出される C ファイル内の関数に対するものですgetqpf.f。たとえば、QESTMは C ファイルの 1 つで関数として として定義されています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 Programmer's Guide (ここから入手可能) では次のように指定されています。

デフォルトのシンボル命名規則は、コンパイラによって異なります。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 コードは(または)qestmという変な名前でシンボルを参照します。もちろん、C 関数の名前として使用する必要があります。ここでのポイントは、引用符内の名前の大文字と小文字が保持されることです。qEsTm_qEsTmqEsTm

于 2012-11-12T20:02:29.273 に答える