Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

problems with netlib PORT library

Knut
Beginner
422 Views

Hi,

I am trying to create a library from the netlib/port sources (http://www.netlib.org/port/) using ifort (64 version 2021.6.0) under Windows 10, Visual Studio 2022.
The library should be called later by a VC++ (MFC) software.

I had compiled with:
ifort /c *.f

The lib was build with:
lib /out:name.lib *.obj      (or shared with:  ifort /dll   *.f)

To see the exports:
dumpbin /EXPORTS name.lib

Unfortunately there are no exports available.

Using gfortran (+dllwrap) all exports are available.

What am I doing wrong?

Thanks,
Knut

0 Kudos
1 Solution
Arjen_Markus
Honored Contributor I
297 Views

There are (at least) two things you can do:

  • Use C macros to translate the name on the C side to the right Fortran name - if you use the Intel Fortran compiler, then this ought to do it:
#define test TEST
#define otherroutine OTHERROUTINE
...
  •  Use a wrapper on the Fortran side that simply passing on the call to the actual FORTRAN routine in the PORT library. Tricky part: the PORT library being old fashioned does not use modules, so all routines are public. That may give linking problems. This solution is more work, but it is independent of the Fortran compiler.

Regards,

 

Arjen

View solution in original post

8 Replies
Steve_Lionel
Black Belt Retired Employee
407 Views

There are no directives in the sources to export DLL entry points. I am not familiar with "dllwrap", but presumably it does something to convert global symbols into DLL exported symbols. You can use a .DEF file, input to the linker, to export selected symbols.

Or you can just use it as a static library, and not need to export DLL entry points.

Arjen_Markus
Honored Contributor I
397 Views

The reason it works with gfortran is that gfortran exports all symbols automatically. It seems to be possible to exclude symbols from being exported, but I have not checked this thoroughly :). You may not want all and every function and subroutine to be exported after all ...

Knut
Beginner
393 Views

OK, thank you.
Then I have two questions:
- How can I create a .DEF file as input for the linker?

- When using a static library:  While linking the (ifort + lib) created "name.lib" in Visual C++, the linker does not find the contained functions. Is there any special calling the functions from VC++?       extern "C" void test-func(...);   seems not working

mecej4
Black Belt
366 Views

Most probably, your linking problems have nothing to do with the PORT or any other library.

Fortran and C use different external name decoration conventions. There is a chapter in the Intel Fortran documentation on Mixed Language Programming, and you need to read most of that chapter, whether you intend to make a static or a dynamic library out of Port.

Microsoft has a page on using DEF files.

Port is old, Fortran IV for the most part, but many of the routines in Port are of high quality. As long as you are content with using the routines in Port without attempting to modify them, you should do fine.

Knut
Beginner
353 Views

Thank you for your comments!
As mentioned before, everything is fine and running with gfortran - including the calls to VC++.
However, with gfortran I have to distribute the MinGW (or cygwin) DLLs with the VC++ application.
That's why (and maybe because of the higher computing speed) my idea was to switch to ifort.

Thanks
Knut

mecej4
Black Belt
325 Views

Users of EXEs and DLLs built using Intel Fortran on Windows who do not have the compiler package installed will need to download and install the Intel Fortran Compiler Runtime for Windows package. 

Knut
Beginner
304 Views

Let me share some efforts around the different behavior of gfortran and ifort in conjunctionwith VC++:

Consider for example:
test.f that contains: SUBROUTINE TEST()

To export TEST with ifort insert "!DEC$ ATTRIBUTES DLLEXPORT :: TEST" directly after "SUBROUTINE TEST()"

Calling from VC++:

static library created by:
gfortran: extern "C" void test_() 
ifort: extern "C" void TEST()

dynamic library:
gfortran + dllwrap (or lib + .DEF):   extern "C" __declspec(dllimport) void test_() 
ifort:   extern "C" void TEST()             (extern "C" __declspec(dllimport) void TEST() works the same)

Miscellaneous:
- If you create libraries with ifort, use /libs:static - then there is no need to provide additional Fortran libraries.
- When using the static ifort library in VC++, the include and lib directory of Intel Fortran must be added to the project settings of the VC++ project under "VC++ directories". For x64 in VS2022:
include:   $(IFORT_COMPILER22)\compiler\include
lib:   $(IFORT_COMPILER22)\compiler\lib\intel64

 

Thank you for your helpful comments!

Arjen_Markus
Honored Contributor I
298 Views

There are (at least) two things you can do:

  • Use C macros to translate the name on the C side to the right Fortran name - if you use the Intel Fortran compiler, then this ought to do it:
#define test TEST
#define otherroutine OTHERROUTINE
...
  •  Use a wrapper on the Fortran side that simply passing on the call to the actual FORTRAN routine in the PORT library. Tricky part: the PORT library being old fashioned does not use modules, so all routines are public. That may give linking problems. This solution is more work, but it is independent of the Fortran compiler.

Regards,

 

Arjen

Reply