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

Error LNK1104 mixed language Fortran library - C++ main program

iberpar
Beginner
870 Views

I'm trying to call a Fortran subroutine from a main program in C++ using Intel compiler integrated in Visual Studio. After compiling the subroutine in a static library .lib and adding it in the source file, as well as providing the path in additional dependencies and finally compiling the main code, I get the error "LNK1104: cannot open file ifmodintr.lib". 

As seen in similar questions, this issue should be solved by following the steps found in the article "Configuring Visual Studio for Mixed-Language Applications", which I did in particularly for VS2017 being my case, but the same error continues appearing. So my questions are:

    - Do I miss something additional within the process or is there another way to solve it?

    - Is it enough to generate a static library or I also need a dynamic one? In the second case, is there a way to generate both at the same time in order to have a dependency between them? (I'm asking this since when creating libraries using another Fortran compiler for its later linkage to a main program on VS, I also add the dynamic one in the same folder as the executable, if not I have accessibility problems to the .dll and the executable does not run.)

Thank you for your help.

0 Kudos
7 Replies
andrew_4619
Honored Contributor II
863 Views
0 Kudos
iberpar
Beginner
809 Views

Hi, thank you for your answer, I have followed the steps on the article found in the solution but I still got the same error. So far I have made it work by adding the static libraries found in the Intel folder (ifconsol.lib, ifmodintr.lib, libifcoremdd.lib, libifportmd.lib, libirc.lib, libmmdd.lib and svml_disspmd.lib) within the source files and the dynamic libraries (libifcoremdd.dll and libmmd.dll) in the same location as the generated executable. It also works by adding the path on Linker->General->Additional Library Directories. These solutions are quite messy and maybe not recommended so I am open to simpler alternatives.  

0 Kudos
mecej4
Honored Contributor III
803 Views

You wrote: "So far I have made it work by adding the static libraries found in the Intel folder (ifconsol.lib, ifmodintr.lib, libifcoremdd.lib, libifportmd.lib, libirc.lib, libmmdd.lib and svml_disspmd.lib) " 

Of these, libifportmd is an import library for libifportmd.dll . Similarly for libifcoremdd. They are not static libraries in the usual sense, i.e., the actual object code for the entry points in these libraries resides in the DLL and not in the LIB. 

Secondly, libraries with names ending in "DD", such as libifcoremdd, are import libraries for debug versions of the DLLs. Unless you have a specific reason to use these debug versions, you should be using the corresponding release versions.

Indiscriminate mixing of static/import and release/debug versions of libraries with just the short term aim of getting the linking to succeed is not a good solution -- the net effect is to create bugs that are encountered at run time rather than link time, and are harder to detect, diagnose and fix.

0 Kudos
iberpar
Beginner
752 Views

Thanks for your answer, thats what I thought. Newly, I have compiled it following a different process which looks more reasonable. 

1. I have created a dll type proyect in Fortran adding the line "!DEC$ ATTRIBUTES DLLEXPORT :: nameofthefunction" within the code in order to generate the .lib at the same time. 

2. Then, I have opened a proyect in C++ as console with the main code program and I have added the .lib into the source foulder.

3. Finally, I have selected the dependency between both and in the properties from the dll proyect - debugging - command, I have introduced the executable path.

Is this the appropriate way of compiling it? Later on I will work with a more complex code and I want to avoid bugs.

0 Kudos
mecej4
Honored Contributor III
734 Views

If you attach the two source files in question (a C file with the main program and another file with a Fortran subroutine) to your reply, I may be able to suggest a solution.

Without knowing what is in those files, and knowing only that the linker did not find a file that it wanted, there are too many wrong paths that one can traverse.

0 Kudos
iberpar
Beginner
717 Views

The code is very simple, just introducing an integer in a main C++ code that calls a Fortran function which returns the squared number.

(.f90) ddl project

module integpower
     use iso_c_binding
     implicit none
     contains
     integer (c_int) function change_integer(a) bind(c)
          !DEC$ ATTRIBUTES DLLEXPORT :: change_integer
          implicit none
          integer (c_int), intent(in) :: a
          integer (c_int), parameter :: power = 2
          change_integer = a ** power
     end function change_integer
end module integpower

(.cpp)  empty console project

#include <iostream>
#include <cstdio>

using namespace std;

extern "C" int change_integer(int* a);

int main()
{
     int a = 5;
     cout << "Fortran integer: " << change_integer(&a) << endl;
     return 0;
}

- .lib file generated from the dll is added into the source folder from the Fortran project. This can be done also in properties -> Linker -> Input -> Additional Dependencies.

- Dependency of the main project with the dll is selected.

- In order to run it, I had to introduce the executable path into properties from the dll project -> debugging -> command.

 

0 Kudos
mecej4
Honored Contributor III
695 Views

The two codes in your last post are fine. With those placed in files iber.f90 and iberc.cpp in a working directory, the following two commands would have built the DLL and the EXE.

ifort /LD /Od iber.f90
icl /Od iberc.cpp iber.lib
0 Kudos
Reply