Fortran链接.so/DLL时公共块TICNBR数据不一致问题
Fortran公共块在MinGW共享库中无法同步的问题
问题场景
主程序TIC和子程序P通过同名公共块TICNBR共享变量itype:
- 子程序
P中修改itype的值 - 将
P编译为p.so共享库后链接生成tic.exe,执行后主程序中itype显示为0,未同步生效 - 直接编译两个源文件生成可执行程序时,变量同步正常
该问题在msys64-mingw64、win64+mingw64环境下均出现,涉及GCC 14.2.0及15.1.0版本,核心原因是公共块被实例化了两份。
原因分析
MinGW环境下编译共享库时,默认会将全局符号(包括Fortran公共块对应的符号)标记为局部符号。这导致主程序和共享库各自创建了独立的公共块实例,二者的内存空间完全分离,因此子程序对变量的修改无法同步到主程序中。而直接编译所有源文件到同一个可执行文件时,所有符号在同一地址空间,公共块自然共享。
解决方案
方案1:编译共享库时导出所有符号
编译子程序生成共享库时,添加链接选项-Wl,--export-all-symbols,强制导出所有全局符号(包括公共块相关符号),确保主程序能绑定到同一个公共块实例:
gfortran -shared -fPIC -Wl,--export-all-symbols p.f90 -o p.so
然后编译主程序并链接共享库:
gfortran tic.f90 p.so -o tic.exe
方案2:在代码中显式导出公共块
在子程序P的公共块声明处添加GCC扩展属性DLLEXPORT,指定该公共块需要被导出:
! 子程序P的代码 SUBROUTINE P INTEGER ITYPE COMMON /TICNBR/ ITYPE !GCC$ ATTRIBUTES DLLEXPORT :: TICNBR ITYPE = 1 RETURN END
然后编译共享库(无需额外导出选项,属性已指定导出):
gfortran -shared -fPIC p.f90 -o p.so
再编译主程序链接共享库即可。
验证
执行生成的tic.exe,此时主程序中应该能正确获取子程序修改后的itype值,不再显示0。
内容的提问来源于stack exchange,提问作者Francois Jacq
相关产品推荐
相关产品推荐

