Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Linking DLL file procedure

Jon_R_
Beginner
1,584 Views

Hi.

I want to include a precompiled DLL library into a Fortran program. The library has been written in C/C++ and the following is provided: a DLL file, a .def file and C++ header files.

In order to include this DLL file with the Fortran Compiler, I first created a .lib file from the .def file (using the lib command from the Microsoft Library Manager, alternatively dlltool from MinGW). The lib file was then put in the same folder as the Fortran source code, and the DLL file was copied to the C:\Program Files (x86)\Intel\Compiler\11.1\067\lib folder. The lib file and the DLL file have the same name. When trying to compile using

ifort nlopttest.f90 libnlopt-0.lib

I get a LNK2019 error which I believe comes from Fortran not being able to locate the DLL file. The lib file appears to be loaded properly. Have I followed the correct procedure for loading DLLs? Is it possible to load the DLL without generating the lib file?

Many thanks.

Jon

 

Ifort output:
--------------------------------------------------------------------------

Microsoft (R) Incremental Linker Version 9.00.21022.08

Copyright (C) Microsoft Corporation.  All rights reserved.

-out:nlopttest.exe

-subsystem:console

nlopttest.obj

libnlopt-0.lib

nlopttest.obj : error LNK2019: unresolved external symbol _NLO_CREATE referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_GET_LOWER_BOUNDS referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_SET_LOWER_BOUNDS referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_SET_MIN_OBJECTIVE referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_ADD_INEQUALITY_CONSTRAINT referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_SET_XTOL_REL referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_OPTIMIZE referenced in function _MAIN__
nlopttest.obj : error LNK2019: unresolved external symbol _NLO_DESTROY referenced in function _MAIN__
nlopttest.exe : fatal error LNK1120: 8 unresolved externals

 

0 Kudos
5 Replies
IanH
Honored Contributor III
1,584 Views

The compiler and linker on Windows do not access the DLL in any way.  The DLL is only searched for and loaded when your program is run.

(Putting third party DLL's in a compiler subdirectory is asking for trouble in future.  Don't do that.  Put the DLL in the same folder as the exe that you are trying to create, or some other independent folder that you add to your path.)

What I suspect is going on is that the linker symbol name that Fortran generates for the references to the procedures in your library are not the same as the actual symbol names in the DLL.  Unless the DLL was generated from Fortran source compiled by the same compiler, you generally need to provide the compiler of code that uses the DLL with additional information, typically via INTERFACE blocks, about the calling conventions associated with the procedures in the DLL (calling convention including aspects such as how to map the name of something in source code to a linker symbol name, amongst other important things)..

Perhaps you could show extracts from the DEF file and the header file for one of the procedures implied by the symbol name in the error messages.

0 Kudos
Jon_R_
Beginner
1,584 Views
Dear Ian. Thank you for the reply. Turns out the DEF file was linking a symbol using underscore, whereas it seems the Fortran compiler did not use that as default. It now working passing “/Qlowercase /assume:underscore” to the ifort compiler. Thanks for your help!
0 Kudos
IanH
Honored Contributor III
1,584 Views
Note there are better ways of specifying calling convention for that sort of case than using compiler options.
0 Kudos
Aaron_H_2
Beginner
1,584 Views

Dear Ian,

What would be the better approach than using "/Qlowercase /assume:underscore" as Jon does? I'm having the same difficulty as he was.

0 Kudos
Steven_L_Intel1
Employee
1,584 Views

Using BIND(C) with the declaration of the procedure in an interface block.

0 Kudos
Reply