共有ライブラリに Fortran サブルーチンを含めると、問題が発生します。このサブルーチンには、名前付き共通ブロックがあります。
この共通ブロックを使用し、共有ライブラリとリンクする Fortran メイン プログラムがあります。
この動作は、サブルーチンまたはメイン プログラムのいずれかで設定された共通ブロック内の変数が 2 つの間で共有されないというものです。
WindowsのMinGWでgfortran 4.9.3を使用しています。これが私の非常に単純な例の一部です。
メインプログラム:
program mainp
common/whgc/ivar
ivar = 23
call sharedf
end
サブルーチン:
subroutine sharedf
common/whgc/ivar
print *, 'ivar=', ivar
end
メイクファイル:
FC = gfortran
FFLAGS=-g
all: shltest.dll mainp.exe
shltest.dll: sharedf.o
$(FC) -shared -o shltest.dll sharedf.o
mainp.exe: mainp.o shltest.dll
$(FC) -o mainp.exe mainp.o shltest.dll
clean:
rm *.o mainp.exe shltest.dll
mainp.exe
を実行するとivar = 0
、正しいのではなく、ivar=23
次のようになりますnm
。
nm -g mainp.o shows:
...
00000004 C _whgc_
nm on sharedf.o shows the same.
nm -g shltest.dll shows:
...
71446410 B _whgc_
nm -g mainp.exe shows:
...
00406430 B _whgc_
これは、_whgc_
mainp.exe の唯一のシンボルです。
ただし、mainp.exe
gdb で実行し、 と の両方にブレーク ポイントを設定する
mainp
と、各ブレーク ポイントでsharedf
のアドレスを出力できます。ivar
アドレスが同じではありません。
動作から、GNU ld がシンボルと正しく一致していないことは明らか_whgc_
ですが、共有ライブラリのビルドまたは最終的なリンクでどのオプションを渡せばよいかわかりません。
(共通ブロックの代替案を提案しないでください。私の実際のアプリケーションでは、共通ブロックを使用するレガシー コードを扱っています。)
編集:
Linux/x86 で私の例を試してみましたが、動作は正しいです。もちろん、Linux では共有ライブラリと実行可能ファイルは ELF 形式のオブジェクトであり、Windows/MinGW では形式は PE/COFF です。