4

I am encountering a problem when I include a Fortran subroutine in a shared library. This subroutine has a named common block.

I have a Fortran main program that uses this common block and links with the shared library.

The behavior is that variables in the common block set in either the subroutine or main program are not shared between the two.

I am using gfortran 4.9.3 under MinGW on windows. Here are the pieces of my very simple example.

Main program:

  program mainp
  common/whgc/ivar
  ivar = 23
  call sharedf
  end

Subroutine:

  subroutine sharedf
  common/whgc/ivar
  print *, 'ivar=', ivar
  end

Makefile:

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

When mainp.exe is run, it produces ivar = 0 instead of the correct ivar=23 Here are the results of some experimentation I did with 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_

This is the only _whgc_ symbol in mainp.exe.

However, when I run mainp.exe in gdb and set break points in both mainp and sharedf, I can print the address of ivar at each break point. The addresses are not the same.

From the behavior it seems clear that GNU ld is not correctly matching the _whgc_ symbols but I'm unclear about what options to pass either in the shared library build or the final link to make it do so?

(Please don't suggest alternatives to common blocks. In my real application I am dealing with legacy code that uses common blocks.)

EDIT:

I tried my example on Linux/x86 and there the behavior is correct. Of course on Linux the shared library and executable are ELF format objects and on Windows/MinGW the format is PE/COFF.

Bill Greene
  • 153
  • 6
  • Yes, I tried that but get this warning message: f951.exe: warning: -fPIC ignored for target (all code is position independent). I'm using a 32-bit compiler on an Intel x86 chipset. And, as expected from the warning, the runtime behavior is the same. – Bill Greene Jan 05 '17 at 19:37
  • On Windows you may need to export/import common blocks explicitly as described [here](https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/347785). – yugr Jan 06 '17 at 06:16
  • I took a look at the link you pointed me to but don't understand why it is relevant to my particular problem. I am using gfortran and from my nm experiments it appears that the common block *is* being exported. Can you be more specific? – Bill Greene Jan 06 '17 at 13:17
  • The link basically says that you need to explicitly mark common blocks as dllimport/export for them to be accessible across dynamic library boundaries on Windows. Here's [gfortran man](https://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directives.html) which says the same. – yugr Jan 06 '17 at 14:04

0 Answers0